Re: LVN_ITEMCHANGING, how can I get it to cancel the change?



Hi Alex, Thank you for the reply.

I only know of _bstr_t to concatenate my strings in COM since it seems to
have more built-in converter than others. If not true then can you recommend
the better one for me to use?

The variable wchar_t* has to use the 'new' keyword first to allocate space,
right? I mean if I just code as follow then would it cause heap corruption?

_bstr_t syUserContextPath = L"LDAP://"; + bstrtServerDomain +
L"/CN=" + userCN + L",CN=Users," + L"CN=" +context +
L",CN=Contexts,CN=Unity,CN=Symark,CN=Program Data" +L"," + bstrDomainOnly;

LPCWSTR lpcSyUserContextPath = syUserContextPath;

The above code will not work right? Becuase I haven't allocated the memory
for lpcSyUserContextPath. Or will the address of syUserContextPath get
assigned to the lpcSyUserContextPath? But when I was in debugging mode, the
syUserContextPath (intellisense) would show as bad pointer.

For example,
m_ObjPath = new WCHAR [wcslen(pwzObjName )+1];
wcscpy(ObjPath , pwzObjName);
wchartServerDomain = wcstok(m_ObjPath, sepsDomain);
wchartServerDomain = wcstok(NULL, sepsDomain);
bstrtServerDomain = wchartServerDomain ;

///// or should it be like beow?
bstrtServerDomain.Assign(W2BSTR(wchartServerDomain));
--
Thanks.


--
Thanks.


"Alexander Nickolov" wrote:

Can you show the relevant code? Qhat you are describing seems
perfectly fine... OTOH I wouldn't recommend _bstr_t for string
manipulation for efficiency reasons...

--
=====================================
Alexander Nickolov
Microsoft MVP [VC], MCSD
email: agnickolov@xxxxxxxx
MVP VC FAQ: http://www.mvps.org/vcfaq
=====================================

"Pucca" <Pucca@xxxxxxxxxxxxxxxxxxxxxxxxx> wrote in message
news:298EBF7A-ABD8-4D90-8675-EA2D27F386ED@xxxxxxxxxxxxxxxx
Thank you Alex. I think I found my problem. I thought the variable type
_bstr_t allocates the memory for me but it doesn't. I use it becuase I
need
to concatenate string a lot in my program. I have been doing something
like
_bstr_t = wchar_t*, assigning either LPWSTR or wchar_t* .. types of
variable
to a _bstr_t variable and it's showing up as <Bad_Ptr> in the debug mode.

I'm trying to figure out how can I assing vaiables like LPWSTR or wchar_t*
to _bstr_t (and make it a good ptr) and I thinkg that would solve most of
my
memory problems.

Thank you and you have a great weekend.
--
Thanks.


"Alexander Nickolov" wrote:

All I can say is try installing the debug symbols and see if you
can make any sense of the reported symbolic location. Most
likely you are corrupting data somewhere, but it's hard to say
what's really going on...

--
=====================================
Alexander Nickolov
Microsoft MVP [VC], MCSD
email: agnickolov@xxxxxxxx
MVP VC FAQ: http://www.mvps.org/vcfaq
=====================================

"Pucca" <Pucca@xxxxxxxxxxxxxxxxxxxxxxxxx> wrote in message
news:B20C2E16-48DF-4472-A995-446761672A60@xxxxxxxxxxxxxxxx
Hi Alex, here's a small addendum to my last email.

After I bring up my user property page in AD and I click the Cancel
button
immediately then it will just close the property page window and return
back
to the Active Directory window. However, if I try to click on the User
property page again or just the computer folder, it will then crash
with
similar message that I mentioned

Unhandled exception at 0x7c8224b2 in mmc.exe: 0xC0000005: Access
violation
reading location 0x0061006e.

Thanks.
--
Thanks.


"Alexander Nickolov" wrote:

First, you don't need to call SetWindowLong/DWL_MSGRESULT
for messages that don't return anything (like WM_INITDIALOG and
WM_COMMAND). Doing so should be harmless, however.

Second, you can use DWLP_USER to set your class' this pointer
directly into the dialog instead of using a global variable. Your
approach should be ok I suppose, since you'll likely never have
the same page activated multiple times...

In your WM_COMMAND handler you cast lParam to NM_LISTVIEW*.
According to the documentation, you get a HWND there, or NULL.
This is most likely the cause of your crash...

--
=====================================
Alexander Nickolov
Microsoft MVP [VC], MCSD
email: agnickolov@xxxxxxxx
MVP VC FAQ: http://www.mvps.org/vcfaq
=====================================

"Pucca" <Pucca@xxxxxxxxxxxxxxxxxxxxxxxxx> wrote in message
news:7EF2F428-86DA-47F8-A0AE-5D724D4C4D8D@xxxxxxxxxxxxxxxx
Hi Alex, Thank you once again. However, my code is crashing every
time
I
do
a return with SetWindowLongPtr in my callback dlgproc. Can you have
a
quick
look and see what I'm doing wrong? For example when the user click
the
Cancel button,
I would be in the debug mode and see that the cursor would get to
the
end
of
the CALLBACK CUserPage::DialogProc modlue ending bracket and the out
poops
the following error message and the Active Directory along with my
page
all
just crash and wiped out. Am I using the SetWindowLongPtr
incorrectly?
Or
do I have heap memory issue? If later, then is there any tool I can
use
in
vs2005 to trace this and fis it? Thanks Alex.

Unhandled exception at 0x776b2c22 in mmc.exe: 0xC0000005: Access
violation
reading location 0x984e87ec.\par


BOOL CALLBACK CUserPage::DialogProc(
HWND hwndDlg, //
handle
to
dialog box
UINT uMsg, //
message
WPARAM wParam, // first
message parameter
LPARAM lParam //
second
message parameter
)
{
HRESULT hResult;
static CUserPage *pThis = NULL;
//*LPNMLISTVIEW pnmv;
NM_LISTVIEW FAR *pnmv;
SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, 0);

switch (uMsg)
{
case WM_INITDIALOG:
//*pThis = NULL;
pThis = reinterpret_cast<CUserPage *>(reinterpret_cast<PROPSHEETPAGE
*>(lParam)->lParam);
pThis->initLoad = true;
hResult = pThis->LoadInitialDialogValues(hwndDlg, pThis->m_ObjPath);
pThis->initLoad = false;
if(SUCCEEDED(hResult))
{ SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, TRUE);
return TRUE;
}
else
{ SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, FALSE);
return FALSE;
}
break;

case WM_COMMAND:
//BN_CLICKED
switch (LOWORD (wParam))
{
case IDC_GENERATE_UNIFID:
pnmv = (NM_LISTVIEW FAR *) lParam;
pThis->iItemIndex = pnmv->iItem;
pThis->GenerateUnifiedID();
SetWindowLongPtr(pThis->hwndDialog, DWLP_MSGRESULT, TRUE);
return TRUE;

//case IDCANCEL://this is MFC, N/A
//EndDialog (hwndDlg, IDCANCEL);
//return TRUE;
}

if (HIWORD(wParam) == EN_CHANGE)
{
if(LOWORD(wParam) == IDC_GECOS_UNIFIEDID)
pThis->UIDChanged = true;
SendMessage(GetParent(hwndDlg), PSM_CHANGED,
(WPARAM)hwndDlg,
0);
}

break;

case WM_DESTROY:
// we don't free the notify handle for property sheets
// MMCFreeNotifyHandle(pThis->m_ppHandle);
break;

case WM_NOTIFY:
if (!pThis->initLoad)
{
switch (((NMHDR *)lParam)->code)
{
case(LVN_ITEMCHANGING):

pnmv = (NM_LISTVIEW FAR *) lParam;

//if validate successfully then retunr FALSE to continue with
// the changes, else if failed then return TRUE to
//dis-allow(cancel) the changes
if (pThis->ValidateChanges(hwndDlg,pnmv))
{ SetWindowLongPtr(pThis->hwndDialog, DWLP_MSGRESULT, FALSE);
return FALSE;
}
else
{ SetWindowLongPtr(pThis->hwndDialog, DWLP_MSGRESULT, TRUE);
return TRUE;
}

case PSN_KILLACTIVE:
pnmv = (NM_LISTVIEW FAR *) lParam;

if (pThis->SaveSyUserData(hwndDlg,pThis->curContext, pnmv->iItem))
{ SetWindowLongPtr(pThis->hwndDialog, DWLP_MSGRESULT, FALSE);
return FALSE; //OK to lose focus and move to othe page
}
else
{ SetWindowLongPtr(pThis->hwndDialog, DWLP_MSGRESULT, TRUE);
return TRUE;//Cancel the user's click to other page
//User has to complete the data or un-check the context access
}
case PSN_APPLY:
// don't notify the primary snap-in that Apply
// has been hit...
// MMCPropertyChangeNotify(pThis->m_ppHandle, (long)pThis);
pnmv = (NM_LISTVIEW FAR *) lParam;
pThis->iItemIndex = pnmv->iItem;
pThis->SaveDialogValues(pThis->hwndDialog, pThis->userPath);
return PSNRET_NOERROR;
case PSN_QUERYCANCEL:
//User Hit the Cancel button, output warning message
//then call the clenaup routine then exit
if(IDYES == MessageBox(NULL, L"Would you like to exit without
saving
the changes?", L"Unity", MB_YESNO | MB_ICONEXCLAMATION))
//pThis->CleanUpExit();
{ SetWindowLongPtr(pThis->hwndDialog, DWLP_MSGRESULT, FALSE);
return FALSE;
}
else
{ SetWindowLongPtr(pThis->hwndDialog, DWLP_MSGRESULT, TRUE);
return TRUE;
}
}//end switch(((NMHDR *)lParam)->code)
}//end if not initLoad
break;
//default:
--
Thanks.


"Alexander Nickolov" wrote:

Slight correction - you _must_ return TRUE, not zero. Returning
FALSE (0) means you didn't process the message. My raw
Win32 API knowledge is a bit rusty...

--
=====================================
Alexander Nickolov
Microsoft MVP [VC], MCSD
email: agnickolov@xxxxxxxx
MVP VC FAQ: http://www.mvps.org/vcfaq
=====================================

"Alexander Nickolov" <agnickolov@xxxxxxxx> wrote in message
news:uU22THEWGHA.1348@xxxxxxxxxxxxxxxxxxxxxxx
Instead of return XXX, do:

SetWindowLong(DWL_MSGRESULT, XXX);
return 0;

E.g. in your example:

if (pThis->ValidateChanges(hwndDlg,pnmv))
SetWindowLong(hwndDlg, DWL_MSGRESULT, FALSE);
else
SetWindowLong(hwndDlg, DWL_MSGRESULT, TRUE);
return 0;

--
=====================================
Alexander Nickolov
Microsoft MVP [VC], MCSD
email: agnickolov@xxxxxxxx
MVP VC FAQ: http://www.mvps.org/vcfaq
=====================================

"Pucca" <Pucca@xxxxxxxxxxxxxxxxxxxxxxxxx> wrote in message
news:5C29D471-02EC-4D38-8605-6C2115AF6F56@xxxxxxxxxxxxxxxx
.


Loading