Hi all, first of all im sorry, this post is gonna be big :\ But i think its time for me to stop coding and ask the pros for help because maybe im doing it all wrong.
My app consist of a main window, with 10 controls created. 4 autocheckboxes, 4 edit fields and 2 pushbuttons (Start, Stop).
It works like this:
1)All the vars are declared, including the ones that relate to the ini and the controls.
<Example>
char strCBGateway[2];
char strValueGateway[50];
</Example>
2)Before the controls are created, ini_READ() is called. This function uses GetPrivateProfileString to get values from myapp.ini and store in variables.
<Example>
...
GetPrivateProfileString("gateway", "state", "1", strCBGateway, 2, "C:\\myapp.ini");
GetPrivateProfileString("gateway", "ip", "Enter a Gateway", strValueGateway, 50, "C:\\myapp.ini");
...
</Example>
2)The controls are created in wm_create.
3)A function called VarsToControls() read the vars and set the controls according to it. If a checkBox is checked, the corresponding EditField should be enabled.
Well everything you saw until now works perfectly, my app is able to start, read the ini, store the ini values in variables, and set the controls acording to this values. Now the problems begin.
Once all that was done, if the user checks, or uncheks any of the checkboxes, the EditFields stay the way they are, they dont change according to the checkboxes. Ok, so what was the idea: Ive created a function called ControlsToVars() which send messages to the controls to get their state and set into that variables.
That way i could catch a event like WM_KILLFOCUS and do like this:
case WM_KILLFOCUS
{
ControlsToVars();
VarsToControls();
}
Yeah but it works like that: Suppose all the controls are checked and all the Edit Fields are enabled and i uncheck all checkboxes. The edit fields keep enabled until i press alt+tab to switch focus between another window and my app window. Then they respond and get disabled...
Off course i thought of using other case but all i tried have failed.
I know the correct thing i should have done from the beginning was catch the click-to-the-checkboxes events at wm_command switch, but when i tried that, i realized i was interrupting the normal behaviour of windows in a way that when the CheckBox received the click, instead of changing it state, it was running my functions but not changing its state.
<Example>
...
case WM_COMMAND:
switch(LOWORD(wParam))
{
case IDC_CHECKGATEWAY: //The functions run but the checkbox does not changes it state. It sux.
{ //Off course: the painting/unpaint of the box was being dealed by ControlsToVars(); //defwindowsproc before ive intercepted this message.
VarsToControls();
return 0;
}
...
</Example>
Oh, you probably should be wondering: Why botter about enabling/desabling this edit fields at run time? Get the state of the controls when the user press the "Start" button, write the ini and go with that :) Yeah i know i could do that, but come on, theres got to be a easy way to do it, almost any app we see can do it. Also, i must keep the vars up-to=date with the controls state because at any time the user can quit the app and the config must be saved correctly to the ini (my function ini_WRITE() gets the values of the vars and write to the ini on WM_CLOSE).
What would you do here to solve this problem? Do you think its time to start the whole thing from beginning or theres still some way to save the day?
Once again, sorry for the big post.
/Alex
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
offhand... and I do mean offhand... as you said "edit fields keep enabled until i press alt+tab to switch focus between another window and my app" I didn't bother to read the code as it should be read in a logic problem... anyway... depending on how you have your window created it may not be getting the proper forced call to update the window... so... try adding an UpdateWindow() call after you set the option (check/unchecked/whatever). Hope that helps... if it don't let us know...
Zero Valintine
PS. I think I speak for everyone (well... everyone who trys to help) when saying...
The more information you give about a problem the better!
The UpdateWindow function updates the client area of the specified window by sending a WM_PAINT message to the window if the window's update region is not empty. The function sends a WM_PAINT message directly to the window procedure of the specified window, bypassing the application queue. If the update region is empty, no message is sent.
BOOL UpdateWindow(
HWND hWnd // handle of window
);
Parameters
hWnd
Identifies the window to be updated.
Return Values
If the function succeeds, the return value is nonzero.
If the function fails, the return value is zero.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
<<case IDC_CHECKGATEWAY: //The functions run but the checkbox does not changes it state. It sux.>>
Are you using autocheckboxes? If not, it's your responsibility to set the state when it is clicked.
Also, when handling messages fiddling with the return value (true or false) sometimes gives unexpected results.
And last: although it won't make a difference in this problem you might want to have a look at dialogboxes. It's a pain in the ... with this amount of controls.
rpeter
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Hi all, first of all im sorry, this post is gonna be big :\ But i think its time for me to stop coding and ask the pros for help because maybe im doing it all wrong.
My app consist of a main window, with 10 controls created. 4 autocheckboxes, 4 edit fields and 2 pushbuttons (Start, Stop).
It works like this:
1)All the vars are declared, including the ones that relate to the ini and the controls.
<Example>
char strCBGateway[2];
char strValueGateway[50];
</Example>
2)Before the controls are created, ini_READ() is called. This function uses GetPrivateProfileString to get values from myapp.ini and store in variables.
<Example>
...
GetPrivateProfileString("gateway", "state", "1", strCBGateway, 2, "C:\\myapp.ini");
GetPrivateProfileString("gateway", "ip", "Enter a Gateway", strValueGateway, 50, "C:\\myapp.ini");
...
</Example>
2)The controls are created in wm_create.
3)A function called VarsToControls() read the vars and set the controls according to it. If a checkBox is checked, the corresponding EditField should be enabled.
<Example>
...
if((strCBGateway[0]=='1') {
SendMessage(hwndCheckServerGATEWAY, BM_SETCHECK, (WPARAM)BST_CHECKED ,(LPARAM)0);
SendMessage(hwndEditServerGATEWAY, EM_SETREADONLY, FALSE, 0);
} else { SendMessage(hwndCheckServerGATEWAY, BM_SETCHECK, (WPARAM)BST_UNCHECKED ,(LPARAM)0);
SendMessage(hwndEditServerGATEWAY, EM_SETREADONLY, TRUE, 0); }
...
</Example>
Well everything you saw until now works perfectly, my app is able to start, read the ini, store the ini values in variables, and set the controls acording to this values. Now the problems begin.
Once all that was done, if the user checks, or uncheks any of the checkboxes, the EditFields stay the way they are, they dont change according to the checkboxes. Ok, so what was the idea: Ive created a function called ControlsToVars() which send messages to the controls to get their state and set into that variables.
<Example>
...
int gateway = SendMessage(hwndCheckServerGATEWAY, BM_GETSTATE, (WPARAM)0, (LPARAM)0);
sprintf(strCBGateway, "%d", gateway);
...
</Example>
That way i could catch a event like WM_KILLFOCUS and do like this:
case WM_KILLFOCUS
{
ControlsToVars();
VarsToControls();
}
Yeah but it works like that: Suppose all the controls are checked and all the Edit Fields are enabled and i uncheck all checkboxes. The edit fields keep enabled until i press alt+tab to switch focus between another window and my app window. Then they respond and get disabled...
Off course i thought of using other case but all i tried have failed.
I know the correct thing i should have done from the beginning was catch the click-to-the-checkboxes events at wm_command switch, but when i tried that, i realized i was interrupting the normal behaviour of windows in a way that when the CheckBox received the click, instead of changing it state, it was running my functions but not changing its state.
<Example>
...
case WM_COMMAND:
switch(LOWORD(wParam))
{
case IDC_CHECKGATEWAY: //The functions run but the checkbox does not changes it state. It sux.
{ //Off course: the painting/unpaint of the box was being dealed by ControlsToVars(); //defwindowsproc before ive intercepted this message.
VarsToControls();
return 0;
}
...
</Example>
Oh, you probably should be wondering: Why botter about enabling/desabling this edit fields at run time? Get the state of the controls when the user press the "Start" button, write the ini and go with that :) Yeah i know i could do that, but come on, theres got to be a easy way to do it, almost any app we see can do it. Also, i must keep the vars up-to=date with the controls state because at any time the user can quit the app and the config must be saved correctly to the ini (my function ini_WRITE() gets the values of the vars and write to the ini on WM_CLOSE).
What would you do here to solve this problem? Do you think its time to start the whole thing from beginning or theres still some way to save the day?
Once again, sorry for the big post.
/Alex
offhand... and I do mean offhand... as you said "edit fields keep enabled until i press alt+tab to switch focus between another window and my app" I didn't bother to read the code as it should be read in a logic problem... anyway... depending on how you have your window created it may not be getting the proper forced call to update the window... so... try adding an UpdateWindow() call after you set the option (check/unchecked/whatever). Hope that helps... if it don't let us know...
Zero Valintine
PS. I think I speak for everyone (well... everyone who trys to help) when saying...
The more information you give about a problem the better!
The UpdateWindow function updates the client area of the specified window by sending a WM_PAINT message to the window if the window's update region is not empty. The function sends a WM_PAINT message directly to the window procedure of the specified window, bypassing the application queue. If the update region is empty, no message is sent.
BOOL UpdateWindow(
HWND hWnd // handle of window
);
Parameters
hWnd
Identifies the window to be updated.
Return Values
If the function succeeds, the return value is nonzero.
If the function fails, the return value is zero.
I second Zero on that....beats the heck out of the "its giving parse error, how do I fix it" crowd...
Wayne
<<case IDC_CHECKGATEWAY: //The functions run but the checkbox does not changes it state. It sux.>>
Are you using autocheckboxes? If not, it's your responsibility to set the state when it is clicked.
Also, when handling messages fiddling with the return value (true or false) sometimes gives unexpected results.
And last: although it won't make a difference in this problem you might want to have a look at dialogboxes. It's a pain in the ... with this amount of controls.
rpeter