Ali Imran
August 3rd, 2005, 05:29 AM
I am trying tp subclass almost all common controls including groupbox, litsbox, radiobutton etc, but for some reason my applciation crashes when I try to define a windowprocedure for my newly created groupbox, listbox, radio etc.
Keeping in mind that I already have many controls of same type in several other dialogs which are not subcalssed. + I am calling the old windowprocedure in the new windowprocedure at end, as:
return CallWindowProc(OldProcs[GetDlgCtrlID(hwnd)], hwnd, message, wParam, lParam);
where OldProcs is an array of type WNDPROC defined as
WNDPROC OldProcs[MAX_CONTROLS];
Each newly created control is given procedure called NewCtrlFormProc, and the old one is saved in OldProcs at certain place.
Kindly direct me the proper way.
regards
mistersulu
August 5th, 2005, 08:23 AM
One possibility: WndProcs are a special windows callback function that must either be a global namespace function or a static class method. I'm not sure if this could be causing your problem.
Another thought: You may want to check the return of "GetDlgCtrlID(hwnd)]". Passing a crazy value to CallWndProc would cause a crash.
Last thing :): It might be a better idea to use a linked-list to store your control IDs because using valid windows IDs as indeces into an array means a rather interesting size. With a list, you could just store the ID as a member (class or struct) and have a FindByID() function return the class/struct.
Hope this helps.
sulu
Ali Imran
August 5th, 2005, 04:32 PM
Thank you for your reply.
I am really new to win32 programming and am not sure if there uis already a stable library for linked lists. Since I always used to create my own String classes Linked list classes and tempalte libraries.
Please guide me.
Runt888
August 5th, 2005, 10:19 PM
The standard template library (STL) has any kind of container you could ever want. C++ also has std::string, so you never really need to create your own.
As for subclassing, I've done something similar. I've found that it's easiest to create a class for each control you want to subclass. For example, a very simple button class might look like this:
class Button
{
public:
Button( const std::string &text );
virtual ~Button();
void createControl( const HWND &parentWindow );
protected:
virtual LRESULT WindowProcedure( HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam );
private:
static LRESULT CALLBACK StaticWindowProcedure( HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam );
std::string mText;
HWND mButtonWindow;
WNDPROC mOriginalWindowProcedure;
};
Button::Button( const std::string &text )
{
mText = text;
mButtonWindow = NULL;
INITCOMMONCONTROLSEX init;
init.dwSize = sizeof( init );
init.dwICC = ICC_STANDARD_CLASSES;
InitCommonControlsEx( &init );
}
void Button::createControl( const HWND &parentWindow )
{
mButtonWindow = CreateWindow( "button", mText, WS_CHILD, 0, 0, 50, 50, parentWindow, NULL, NULL, NULL );
if( mButtonWindow != NULL )
{
//Set the pointer to this class.
SetWindowLongPtr( mButtonWindow, GWLP_USERDATA, (LONG_PTR)this );
//Subclass the control.
mOriginalWindowProcedure = (WNDPROC)SetWindowLongPtr( mButtonWindow, GWL_WNDPROC, (LONG_PTR)StaticWindowProcedure );
}
}
LRESULT Button::WindowProcedure( HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam )
{
return CallWindowProc( mOriginalWindowProcedure, hwnd, message, wParam, lParam );
}
LRESULT CALLBACK Button::StaticWindowProcedure( HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam )
{
Button* button = reinterpret_cast<Button*>( GetWindowLongPtr( hwnd, GWLP_USERDATA ) );
return button->WindowProcedure( hwnd, message, wParam, lParam );
}
With this class (obviously you would need to add some stuff for controlling styles, changing text, resizing, etc) you don't need a bunch of arrays to store window handles and old window procedures. Instead, if you need a subclassed button, derive a class from Button and overload the WindowProcedure function.
Let me know if you need me to go into more details with any of this.
Kelly
p.s. I wrote the above class from memory, so it might not be perfect, but it should be pretty close.