Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations strongm on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

window subclassing problem

Status
Not open for further replies.

wduty

Programmer
Jun 24, 2000
271
US
I have three child windows in the main HWND of a program. I am subclassing one of them so as to be able to do some custom mouse-handling in that child. The callback I assign only seems to stick if I use GetChildFromPoint() when I switch the procedures. Attempting to use the window handle itself doesn't work. (????)

With everything else held constant:

originalProcHandle = SetWindowLong(hChildHandle, GWL_WNDPROC, (DWORD)mycallback);

fails

POINT p; p.x = 203; p.y = 5;
originalProcHandle = SetWindowLong(ChildWindowFromPoint(hMain, p), GWL_WNDPROC, (DWORD)mycallback);

works

This will work for the present case because I know the starting positions of all the windows but if I were to use this in situations where the starting positions might be variable it would not work or would be require extra coding.

Anyone ever experience this?
--Will Duty
wduty@radicalfringe.com

 
Hi Will,
there are several points to follow while subclassing a window or a control. U can find them in MSDN's Creating a SubClass
There r few CWnd class functions that u can use for subclassing like..

1. SubclassWindow( HWND )
OR
2. SubclassDlgItem( UINT , CWnd* )
To this function u pass the control’s ID and the control’s parent, which is ur main window.

This function dynamically subclasses a window and attaches it to CWnd object. When a window is dynamically subclassed, windows messages will route through the CWnd’s message map and call message handlers in the CWnd’s class first. Messages that are passed to the base class will be passed to the default message handler in the window/control.

What it does is like this..It attaches the Windows control to a CWnd object and replaces the window’s WndProc and AfxWndProc functions. Here's where one may tend to go wrong, ie to restore old pointer back when done.
The function stores a pointer to the old WndProc in the CWnd object.


class CMyButton : public CButton {...};
// m_myButton is a CMyButton object member of CAboutDlg

Code:
BOOL CAboutDlg::OnInitDialog() 
{
   CDialog::OnInitDialog();
   // IDC_BUTTON1 is the ID for a button on the 
   // dialog template used for CAboutDlg.
   m_myButton.SubclassDlgItem(IDC_BUTTON1, this);   

   return TRUE;   // Return TRUE unless you set the focus to a control
                  // EXCEPTION: OCX Property Pages should return FALSE
}

For more information refer to MSDN.
Thanks and regards,
Hemant.
 
Thanks for your suggestion but it's not an MFC program. It's a Win32 implementation of a window splitter. The question was not so much how to get subclassing to work (because it is working) but why I can get the child window's procedure pointer from ChildWindowFromPoint() but not from the window handle itself:


LRESULT CALLBACK WndProc(HWND hWnd, UINT Message, WPARAM wParam, LPARAM lParam)
{
RECT r;
POINT p;
p.x = gnLeft + 1;
p.y = 10;
switch(Message)
{
case WM_CREATE:
ghSplitter = CreateWindow("STATIC", "", WS_CHILD | WS_THICKFRAME,
gnLeft, 0, gnLeft + nSpltWidth, 0, hWnd, NULL, ghInst, NULL);
ghList = CreateWindowEx(WS_EX_CLIENTEDGE, "LISTBOX", "", WS_CHILD ...);
ghEdit = CreateWindowEx(WS_EX_CLIENTEDGE, "EDIT", "", WS_CHILD ...);
SetForegroundWindow(ghSplitter);

gOrigSplitterProc = (WNDPROC) SetWindowLong([red]ChildWindowFromPoint(hWnd, p)[/red],
GWL_WNDPROC, (DWORD)SplitterSubClassProc);

// I should be able to use ghSplitter


break;

case WM_SIZE:
GetClientRect(hWnd, &r);
MoveWindow(ghList, 0, 0, gnLeft, r.bottom, TRUE);
MoveWindow(ghSplitter, gnLeft, 0, nSpltWidth, r.bottom, TRUE);
MoveWindow(ghEdit, gnLeft + nSpltWidth, 0, r.right - (gnLeft + nSpltWidth), r.bottom, TRUE);
break;

default: return DefWindowProc(hWnd, Message, wParam, lParam);
}
return 0;
}


LRESULT CALLBACK SplitterSubClassProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
messages...

return CallWindowProc(gOrigSplitterProc, hWnd, msg, wParam, lParam);
}

rest of program...
--Will Duty
wduty@radicalfringe.com

 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top