Matty? How did you do it then in SendTo? Doesn't that script use the NMHDR structure or somthing very similar too....?
quote:
Originally posted by Matty
quote:
Originally posted by deAd
code:
var pNmhdr = Interop.Allocate(12); // if this is the wrong size sorry
Interop.Call('Kernel32.dll', 'RtlMoveMemory', pNmhdr.DataPtr, lParam, pNmhdr.Size);
// do stuff with pNmhdr
The members of the structure are still 0... I don't see why this isn't working
Because you've sent the notification message yourself:
code:
case WM_PARENTNOTIFY:
_sent_notify = true;
Interop.Call('user32', 'SendMessageW', _window.Handle,
WM_NOTIFY,
pPlusWnd.GetControlHandle('tvFiles'),
NMHDR.DataPtr);
but you don't fill the structure with the proper values.
----------------------
quote:
Originally posted by Matty
So my dilemma is the website example says that lParam is the NMHDR structure however there would be no way to access the members of the structure.
I could be wrong, but I think you're confusing some things.
Anyways, some stuff about the NMHDR structure when it is send from a control by Windows itself:
lParam points to an _extended_ NMHDR structure. This means, in the OnWndAllContactsEvent_MessageNotification, you need to copy the entire structure in memory to a datablock. This is done with the RtlMoveMemory API, as you already know.
But before you do this, you first need to check several things, so you don't copy unallocated memory (as not every extended structure used by the specific notification messages is the same size). But the basic NMHDR structure is always 12 bytes long of course.
And thus depending on the
code member of the structure, the structure will actually be x bytes bigger. The
code member is that notification code. (thus of which each uses their own extended NMHDR structures. thus which all begin with the basic NMHDR structure again).
So, from "the top of my head" (almost, as I use this very same code "somewhere" already
):
code:
function OnWndAllContactsEvent_MessageNotification(pPlusWnd, nMessage, wParam, lParam) {
// Allocate enough memory immediatly for the extended structure we're going to use
var _NMHDR = Interop.Allocate(72);
// Copy only the basic needed members (at first)
// (<= come to think of it, this needs to be fixed in SendTo )
Interop.Call('Kernel32', 'RtlMoveMemory', _NMHDR.DataPtr, lParam, 12);
// Check the code member.
if (_NMHDR.ReadDWORD( 8) === /* LVN_BEGINLABELEDIT */ -175) {
// If it is the correct one, we can copy the rest of the needed bytes safely
Interop.Call('Kernel32', 'RtlMoveMemory', _NMHDR.DataPtr + 12, lParam + 12, 60);
Debug.Trace('0 HWND hwndFrom; ' + _NMHDR.ReadDWORD(0));
Debug.Trace('4 UINT idFrom; ' + _NMHDR.ReadDWORD(4));
Debug.Trace('8 UINT code; ' + _NMHDR.ReadDWORD( 8));
Debug.Trace('12 UINT mask; ' + _NMHDR.ReadDWORD(12));
Debug.Trace('16 int iItem; ' + _NMHDR.ReadDWORD(16));
Debug.Trace('20 int iSubItem; ' + _NMHDR.ReadDWORD(20));
Debug.Trace('24 UINT state; ' + _NMHDR.ReadDWORD(24));
Debug.Trace('28 UINT stateMask; ' + _NMHDR.ReadDWORD(28));
Debug.Trace('32 LPTSTR pszText; ' + _NMHDR.ReadDWORD(32));
Debug.Trace('36 int cchTextMax; ' + _NMHDR.ReadDWORD(36));
Debug.Trace('40 int iImage; ' + _NMHDR.ReadDWORD(40));
Debug.Trace('44 LPARAM lParam; ' + _NMHDR.ReadDWORD(44));
Debug.Trace('48 int iIndent; ' + _NMHDR.ReadDWORD(48));
Debug.Trace('52 int iGroupId; ' + _NMHDR.ReadDWORD(52));
Debug.Trace('56 UINT cColumns; ' + _NMHDR.ReadDWORD(56));
Debug.Trace('60 PUINT puColumns; ' + _NMHDR.ReadDWORD(60));
Debug.Trace('64 int* piColFmt; ' + _NMHDR.ReadDWORD(64));
Debug.Trace('68 int iGroup; ' + _NMHDR.ReadDWORD(68));
}
or in your case (which doesn't actually use an extended NMHDR structure though):
code:
case WM_NOTIFY:
_get_item(pPlusWnd);
if (_sent_notify == true){
Interop.Call('kernel32', 'RtlMoveMemory', NMHDR, lParam, 12);
Debug.Trace(NMHDR.ReadDWORD(0));
Debug.Trace(NMHDR.ReadDWORD( 8)); // this is your NM_CLICK, NM_DBLCLK, etc notification code
But of course, the members of the structure you read here are filled in by you (or rather, not filled in) so they just return what you've put there: nothing.
-----------
Part 2:
So what do you fill in in that NMHDR structure in the WM_PARENTNOTIFY case? That depends on the values of lparam and wparam. eg: if the low-order word of wParam is WM_LBUTTONDOWN, you should fill he structure with the appropiate handle of the control, the id, and NM_CLICK as code member.
But as far as double clicking goes,
this needs to be detected by your own custom code. This means you need to catch two WM_LBUTTONDOWN's in a row in a certain time, and then you could fill in the NMHDR structure with NM_DBLCLK. In other words, if that event occurs, you would have recieved in the WM_NOTIFY case of your code 1 NM_CLICK and milliseconds later (depending on how long you set your timer to detect a doubleclick) one NM_DBLCLK. see WM_LBUTTONDBLCLK.
This brings up the fact that sending your own WM_NOTIFY message is actually useless, as you could just as well handled the double clicking (whatever the effect is you want) directly in the WM_PARENTNOTIFY case.
This said, and this might be a dumb comment, but why don't you use the WM_NOTIFY messages send from the control itself? They will contain all those specific notification messages already. Or aren't they send to the parent window for a TreeView? (I know some stuff for a listview isn't send to the parent either, so I wouldn't be surpised of it actually)...