|
Your page variables (i.e., the ones used by AddPage() ) should be members of CMainFrame , not local to OnAddClassInfo() . What type of object is ClassInfo ?
Other than that, you need to step through the code using the debugger.
You might be better served by letting the MFC framework create a wizard-based app for you. You can customize it from there.
"One man's wage rise is another man's price increase." - Harold Wilson
"Fireproof doesn't mean the fire will never come. It means when the fire comes that you will be able to withstand it." - Michael Simmons
"You can easily judge the character of a man by how he treats those who can do nothing for him." - James D. Miles
|
|
|
|
|
ClassInfo inherits from CPropertyPage, while the other objects inherit from CPropertyPage.
The program successfully displays the wizards start page, but once I click next, this access violation occurs
Debugging shows that the access violation occurred in the following function:
int ClassName::LoadSchoolName()
{
CComboBox *pSchoolName = (CComboBox *)GetDlgItem(IDC_COMBO1);
char szString[100];
TCHAR szString1[100];
INT_PTR iSchInfoID;
try
{
char szDatabaseFile[100];
GetDatabaseA(szDatabaseFile,sizeof(szDatabaseFile));
CppA::CppSQLite3DB db;
db.open(szDatabaseFile);
StringCbCopyA(szString,sizeof(szString),"SELECT SchInfoID,SchName,SchCity,SchState,SchCountry FROM SchInfo");
CppA::CppSQLite3Query q = db.execQuery(szString);
if(q.fieldIsNull(0))
{
return 0;
}
size_t size;
const char *p;
while (!q.eof())
{
TCHAR szMySchName[50],szMySchCity[20],szMySchState[20],szMySchCountry[20];
long long iSchoolInfoID;
for (int fld = 0; fld < q.numFields(); fld++)
{
switch(fld)
{
case 0:
{
iSchoolInfoID = q.getInt64Field(0);
}
break;
case 1:
{
p = q.getStringField(1);
DecryptString(const_cast<char *>(p),szString);
mbstowcs_s(&size,szString1,sizeof szString1,szString,lstrlenA(szString));
StringCbCopy(szMySchName,sizeof(szMySchName),szString1);
}
break;
case 2:
{
p = q.getStringField(2);
DecryptString(const_cast<char *>(p),szString);
mbstowcs_s(&size,szString1,sizeof(szString1),szString,lstrlenA(szString));
StringCbCopy(szMySchCity,sizeof(szMySchCity),szString1);
}
break;
case 3:
{
p = q.getStringField(3);
DecryptString(const_cast<char *>(p),szString);
mbstowcs_s(&size,szString1,sizeof(szString1),szString,lstrlenA(szString));
StringCbCopy(szMySchState,sizeof(szMySchState),szString1);
}
break;
case 4:
{
p = q.getStringField(4);
DecryptString(const_cast<char *>(p),szString);
mbstowcs_s(&size,szString1,sizeof(szString1),szString,lstrlenA(szString));
StringCbCopy(szMySchCountry,sizeof(szMySchCountry),szString1);
}
break;
}
}
TCHAR szSchoolName[100];
StringCbPrintf(szSchoolName,sizeof szSchoolName,_T("%s,%s,%s,%s"),szMySchName,szMySchCity,szMySchState,szMySchCountry);
int i = pSchoolName->AddString(szSchoolName);
pSchoolName->SetItemData(i,(DWORD_PTR)iSchoolInfoID);
q.nextRow();
}
pSchoolName->SetCurSel(0);
return 1;
}
catch(CppA::CppSQLite3Exception & e)
{
char szString[100];
StringCbPrintfA(szString,sizeof(szString),"Error Code: %d\n Error Mesage: %s",e.errorCode(),e.errorMessage());
MessageBoxA(NULL,szString,"Load shc name Error",MB_OK);
return 0;
}
catch(double dError)
{
return 0;
}
return 0;
}
Actually, at the start the property page objects were members of the PropertySheet object.
Also, initially, the LoadSchoolName function was part of a win32 dll( I made it so for maintenace purpose) which the MFC extension dll ClassInfo.dll load or links with.
But when access violation kept occuring at that location of the function, I decided to make the function a member function in the MFC extension DLL, rather that a win32 dll.
Well, that did not solve the problem. So, I read through msdn and saw that example on DoModal() did not make the property pages member of the propertysheet object, so I decided to try that next, but still the same problem.
Shown below is the function that calls the LoadSchoolName function:
BOOL ClassName::OnInitDialog()
{
CPropertyPage::OnInitDialog();
ClassInfo * pPropertySheet = (ClassInfo *)m_Pointer;
LoadSchoolName();
CComboBox *pCombo2 = (CComboBox *)GetDlgItem(IDC_COMBO2);
int i = 0;
while(*szClassType[i])
{
pCombo2->AddString(szClassType[i]);
i++;
}
pCombo2->SetCurSel(0);
return TRUE; }
The OnInitDialog function loads various school names from data base and uses them to fill the stated combobox. Like I said the wizard displays the wizard's start page , but each time I click next, the the access violation occurs.
If I comment out the LoadSchoolName function, the wizard successfully load the next Property page , but with an empty combobox.
So I decided to replace the combobox pointer in the LoadSchoolName function with a
CArray<ULONG_PTR> Object( I cast each SchoolName TCHAR pointer to ULONG_PTR using a reinterpret_cast. So that I call add the strings to the combobox from the CArray object.
On doing this , access violation occures at the point in the code where I call CArray
<ULONG_PTR>.Add( ).
It appears thar whetther I try to add the string to a combobox or an array, each time I attempt to addd the school name string, access violation occurs. I don't just understand why.
Can some one here, help?
|
|
|
|
|
You are formatting quite a lot of things into the school name. Maybe you create more than 100 characters and the StringCbPrintf() doesn't add the terminating \0 character in that case. You could try
szSchoolName[99] = 0;
before calling AddString() and see if that changes anything.
The good thing about pessimism is, that you are always either right or pleasently surprised.
|
|
|
|
|
You seem to be mixing char and TCHAR somewhat indiscriminately, and you should not be using TCHAR as the destination of mbstowcs_s . This may well be where you are going wrong.
|
|
|
|
|
I found out the problem. I passed the size of the wide-char buffer in bytes to mbstowcs_s rather than the size in WORDS.
Immediately I corrected this, everything started working fine.
Thanks a lot.
|
|
|
|
|
Hi,
I read that i can set a variable in flash memory like this (PIC32):
uint8 Gain_factor_Den_17[128] __attribute__((space(prog), section(".table_flash_control")));
But what happens when i change that variable, flash has some requirements (e.g. need to erase page before writing etc). Who will handle that?
|
|
|
|
|
The variable is read only for your program. It is up to you to handle writing to it.
See the Microchip article Data EEPROM Emulation for PIC18, PIC24, dsPIC, PIC32[^]. There is also a library that emulates an EEPROM using the program flash memory.
But you should take care of the limited write endurance of your PIC device. If you need to change the variable frequently, you should use an external EEPROM.
|
|
|
|
|
Thanks for the response, but i am still a little confused.
Just theoretically, what happens if i were to write:
uint8 Table[128] __attribute__((space(prog), section(".table_flash_control"))); ...
Table[0] = 13;
Unfortunately i cannot try it, just trying to understand the logic. I am aware that the flash memory has only some certain write lifespan.
|
|
|
|
|
The flash memory of the PIC controllers is the program memory where code is stored. You can initialize the variable at compile time and it will be written together with the program code.
To write to the program memory by the running program you need to execute special instructions. For the PIC 32 see section 5. Flash Programming[^ PDF] of the PIC32 Family Reference Manual.
A compiler or assembler may provide functions or macros to perform the writing or compilers may have built-in support for writing. So the answer if the value is written depends on the used compiler. But if the compiler does not support writing to flash memory, you will get an error at compile time.
|
|
|
|
|
Thanks, that clears it up!
|
|
|
|
|
I noticed in the microsoft windows library they had two versions of what i assumed with similar files.
filename.h/filename.cpp and filenameEx.h/filenameEx.cpp
Anyone know how this "Ex" suffix is used? and what the relationship if any between the non-Ex and the "Ex" version?
Kind regards,
David
|
|
|
|
|
it really depends on the company/implementation - I doubt there's any 'standard' meaning, eg 'Example', 'Extension' - the only way to know for sure is a side-by-side comparison using [insert name of your favourite diff/compare tool here]
|
|
|
|
|
david21742 wrote: Anyone know how this "Ex" suffix is used? and what the relationship if any between the non-Ex and the "Ex" version? I always interpreted it as an "extended" version.
"One man's wage rise is another man's price increase." - Harold Wilson
"Fireproof doesn't mean the fire will never come. It means when the fire comes that you will be able to withstand it." - Michael Simmons
"You can easily judge the character of a man by how he treats those who can do nothing for him." - James D. Miles
|
|
|
|
|
Basically it stands for an extended version.
Microsoft follows 2 conventions for extensions or newer versions of files / APIs / classes.
MFC has a CDialog class which is now extended to CDialogEx .
CDialogEx exists in a file called AfxDialogEx.h
There are several extended versions of APIs that follow this convention -
CreateWindow - CreateWindowEx
RegOpenKey - RegOpenKeyEx
The other convention that is followed is to add the numbers 2, 3, 4 ... to the end of the name.
Files that follow this convention are -
AfxPriv.h , AfxPriv2.h
AfxCmn.inl , AfxCmn2.inl , AfxCmn3.inl
This convention is followed by the COM interfaces -
IClassFactory , IClassFactory2
IPersistFolder , IPersistFolder2 , IPersistFolder3
«_Superman_»
I love work. It gives me something to do between weekends.
Microsoft MVP (Visual C++) (October 2009 - September 2013) Polymorphism in C
|
|
|
|
|
thank you very much. i had to name something where it was in appropriate to overload, and I couldn't think of an appropriate name. i saw something in microsoft's thread or mutex library that used that naming convention. I should have realized Ex meant "extended", duh. Kind regards,
|
|
|
|
|
I have an ATL dialog based applications.
I have a custom list control derived from CListCtrl with message map
BEGIN_MESSAGE_MAP( MyListCtrl, CListCtrl )
ON_NOTIFY_REFLECT( NM_CUSTOMDRAW, &MyListCtrl::OnNMCustomDraw )
END_MESSAGE_MAP()
void MyListCtrl, ::OnNMCustomDraw( NMHDR *pNMHDR, LRESULT *pResult )
{
NMLVCUSTOMDRAW* pLVCD = reinterpret_cast<nmlvcustomdraw*>( pNMHDR);
// Take the default processing
*pResult = CDRF_DODEFAULT;
if( CDDS_PREPAINT == pLVCD->nmcd.dwDrawStage )
{
*pResult = CDRF_NOTIFYITEMDRAW;
}
else if( CDDS_ITEMPREPAINT == pLVCD->nmcd.dwDrawStage )
{
int nRow = static_cast<int>(pLVCD->nmcd.dwItemSpec );
if( true == MyArray[nRow].bIsOlder )
{
pLVCD->clrText = RGB( 128, 128, 128 );
}
pResult = CDRF_DODEFAULT;
}
}
But I am not getting ant reflected message from the parent dialog.
I know that it can be done by using the REFLECT_NOTIFICATIONS() in the parent class. But I read that we have to derive the CListCtrl from CContained window. Is it the right way, if so what are things I have to take care.
Is there any better solution to resolve this issue?
aks
|
|
|
|
|
|
Hello everyone, there is an article in Chinese discussing MS Detours API hooking library and Mhook library. I don't understand how to download the attachment and I can't understand the article. Could anyone who understands Chinese help me out here? Much appreciated in advance!! Please
|
|
|
|
|
well, you might want to include the link to the article so people can find it
|
|
|
|
|
|
|
You're right. It's already been posted there now. Thanks
|
|
|
|
|
Based on the "Visual C++ 2008 Feature Pack" sample VisualStudioDemo
I have a toolbar (CMFCToolbar) in a docking pane (CDockPane) that contains operations to be done on the content of the docking pane.
Currently, all the toolbar buttons are "aligned" from the left side; as it is expected when working with a toolbar.
Is there a way to move the right-most button in the toolbar to be at the right-most side or the rect (of the toobar) ?
for example ( in ascii art) to have something like this (toolbar is between [] )
==================================================
| [button1|button2|button3| button4] |
|------------------------------------------------|
| |
The toolbar rect spans the whole width of the docking pane (also resizes when the docking pane resizes)
Looking at the CMFCToolbar documentation and code (afxtoolbar.cpp/.h) does not seem to offer some API to do that.
So, Am I chasing a wild goose?
Thanks.
Max.
I'd rather be phishing!
|
|
|
|
|
Yes, of course...
void CYourToolBar::AdjustLocations()
{
__super::AdjustLocations();
if (GetSafeHwnd())
{
int iCount(GetCount());
if (iCount)
{
CRect crClient(0, 0, 0, 0);
GetClientRect(crClient);
CMFCToolBarButton* pcButton(GetButton(iCount - 1));
if (pcButton)
{
CRect crPos(pcButton->Rect());
if (crClient.right > crPos.right)
{
crPos.OffsetRect(crClient.right - crPos.right, 0);
pcButton->SetRect(crPos);
UpdateTooltips();
}
}
}
}
}
They sought it with thimbles, they sought it with care;
They pursued it with forks and hope;
They threatened its life with a railway-share;
They charmed it with smiles and soap.
modified 12-Dec-14 7:37am.
|
|
|
|
|
Excellent !!!
plug the code right in and works nearly ok; I have some minoe redraw issue that should be easy to track down.
Thanks.
I'd rather be phishing!
|
|
|
|
|