I'm working on my own personalized winapi wrapper. My desired syntax is such:
// #define wndproc(name) void name (Window & hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
// #define buttonproc(name) void name (Button & hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
wndproc (rightClick) { //evaluates to function to handle window message
::msg ("You right clicked the window. Closing window...");
hwnd.close(); //close() is implemented in my Window class
}
buttonproc (buttonClick) { //same thing basically
::msg ("You clicked this button. I'm going to hide the other one...");
//if text on this button is "One button", find the one belonging to parent
//with the text "Other button" and hide it, or vice-versa
hwnd.text == "One button"
? hwnd.parent().button ("Other button").hide();
: hwnd.parent().button ("One button").hide();
}
int main() {
Window win; //create default window
win.addmsg (WM_LBUTTONDOWN, rightClick); //look for l-click message and call that
Button b1 (win, "One button", 100, 100, 50, 20, buttonClick); //parent, coords, size, clicked
Button b2 (win, "Other button", 200, 100, 50, 20, buttonClick);
return messageLoop(); //should be self-explanatory
}
The thing is, in wndproc
, hwnd
is a Window &
and in buttonproc
, hwnd
is a Button &
. I might be able to get away with saying:
msgproc (Window, rightClick){...}
msgproc (Button, buttonClick){...}
The problem is in the fact that I have to call these procedures and give them the right hwnd
. My main window procedure is implemented in my Window
class. It gets the four normal arguments. If I need to pass on a WM_COMMAND
message to the right button procedure, I'd like to give it the corresponding Button
object.
The way it is currently, I pass a pointer to the superclass of both Window
and Button
. Of course it creates convoluted code such as:
((Window *)hwnd)->operator()() //get HWND of the Window
It doesn't seem to really work that well anyways. Unfortunately, the only way I can think of at the moment to do so is to keep a list of every Button
created and pull the right one out. I could even extend this to all possible recipients.
The advantage to doing it this way is that my Button
class has a static window procedure that is called any time a WM_COMMAND
message is found. I haven't added other controls, but it is designed to work by checking the id with existing ones and calling the procedure you specify when you create the button if it's a match. The thing is, when this is done, any other things (like a checkbox) that add the WM_COMMAND
handler will be called as well.
I was thinking of keeping a list in Window
of every HWND child and its corresponding object. This way I can just nuke the extra procedures in every class like the Button
, which will cause a lot of extra processing to occur, and replace proc [i] ((BaseWindow *)hwnd, msg, wParam, lParam)
with something like proc [i] (control [loword(wParam)], msg, wParam, lParam)
for WM_COMMAND
, using lParam
to see whether it's a control.
It seems like I'm missing something big though. Chances are I'll start to implement this and then run into a major problem. Is there a better way to do all of this?
While I'm at it, is there a way to make a control()
function that returns the correct object type (Button, Checkbox...) depending on which one it finds the id to correspond to instead of just an array of varying objects (which I'm pretty sure I've seen a way to do)?