I posted recently about trying to make a tabcontrol with dialogs on it, well I've done a little more research on the problem.
I reduced my program down to a modeless dialog as a child of the main window. In the .RC file the dialog includes the WS_CHILD style, yet when the window is moved the dialog does not move with it. if I then add a line
SetParent(hDlg,hwnd);
where hDlg is the dialog handle and hwnd is the window handle the dialog now moves with the window. I would expect using WS_CHILD should set the parent without having to do it explicitly.
I also notice that after adding the SetParent line, the dialog doesn't always appear in the same place on the window when the program is run, should it not use the coordinates in the dialog definition?
One more thing.. If I specify the dialog coordinates as 0, 0, 100, 100 in the .RC file it appears to display at twice that size. If I then us MoveWindow with the same coordinates the dialog shrinks down to the expected size.
So.. am I missing something, or is this some kind of bug?
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Here's the code, the dialog is at the end.
I took out pretty much everything but the basics. You should see a commented out SetParent line, uncomment it to see the difference.
wcl.lpszMenuName = NULL; /* no main menu */
wcl.cbClsExtra = 0; /* no extra */
wcl.cbWndExtra = 0; /* information needed */
/* Make the window white. */
wcl.hbrBackground = (HBRUSH) GetStockObject(WHITE_BRUSH);
/* Register the window class. */
if(!RegisterClassEx(&wcl)) return 0;
/* Now that a window class has been registered, a window
can be created. */
hwnd = CreateWindowEx(
0,
szWinName, /* name of window class */
"Using a Tab Control", /* title */
WS_OVERLAPPEDWINDOW, /* window style - normal */
CW_USEDEFAULT, /* X coordinate - let Windows decide */
CW_USEDEFAULT, /* Y coordinate - let Windows decide */
CW_USEDEFAULT, /* width - let Windows decide */
CW_USEDEFAULT, /* height - let Windows decide */
HWND_DESKTOP, /* no parent window */
NULL, /* no override of class menu */
hThisInst, /* handle of this instance of the program */
NULL /* no additional arguments */
);
hInst = hThisInst; /* save the current instance handle */
/* Display the window. */
ShowWindow(hwnd, nWinMode);
UpdateWindow(hwnd);
/* Create the message loop. */
while(GetMessage(&msg, NULL, 0, 0))
{
if(!IsDialogMessage(hDlg, &msg)) {
TranslateMessage(&msg); /* translate keyboard messages */
DispatchMessage(&msg); /* return control to Windows 98 */
}
}
return msg.wParam;
}
/* This function is called by Windows 98 and is passed
messages from the message queue.
*/
LRESULT CALLBACK WindowFunc(HWND hwnd, UINT message,
WPARAM wParam, LPARAM lParam)
{
switch(message) {
case WM_CREATE:
hDlg = CreateDialog(hInst, "MyDB1", hwnd,
(DLGPROC) DialogFunc1);
// SetParent(hDlg,hwnd);
// MoveWindow(hDlg, 2, 16, 158, 106, 1);
break;
case WM_PAINT:
break;
case WM_DESTROY: /* terminate the program */
if(hDlg) DestroyWindow(hDlg);
PostQuitMessage(0);
break;
default:
/* Let Windows 98 process any messages not specified in
the preceding switch statement. */
return DefWindowProc(hwnd, message, wParam, lParam);
}
return 0;
}
/* dialog function. */
BOOL CALLBACK DialogFunc1(HWND hdwnd, UINT message,
WPARAM wParam, LPARAM lParam)
{
switch(message) {
case WM_COMMAND:
switch(LOWORD(wParam)) {
case IDOK:
PostQuitMessage(0);
return 1;
}
}
return 0;
}
Well, Mingw uses the Windows system libraries as every other compiler (e.g. VC), so it should behave in the same way regardless of the compiler used.
Why it doesn't work... it's odd to use a dialog to be inserted in a window, but it might be done. Remember that the dialog window created with CreateDialog is independent from the others you created before.
Hope this helped anyway, sorry if not.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Okay thanx, I was pretty much coming to the conclusion that a dialog was not what I need for a tab control even though the example in the book did it that way. I think what I need to use is a static window, haven't tried it yet though.
Basically what I'm trying to do is rewrite a program I did in RapidQ (an object oriented BASIC) in C++.
It's a kind of database that uses a whole bunch of edit controls to input the data, the edits are divided onto the tabs of a tabcontrol. One tab can have up to 128 edits on it, so I need to arrange them all on some kind of parent controls (in RapidQ they have a panel control that I use for this) and then just switch between which parent control is shown when a tab is selected. Hopefully a Static window will work, unless someone else has a better suggestion..
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
I posted recently about trying to make a tabcontrol with dialogs on it, well I've done a little more research on the problem.
I reduced my program down to a modeless dialog as a child of the main window. In the .RC file the dialog includes the WS_CHILD style, yet when the window is moved the dialog does not move with it. if I then add a line
SetParent(hDlg,hwnd);
where hDlg is the dialog handle and hwnd is the window handle the dialog now moves with the window. I would expect using WS_CHILD should set the parent without having to do it explicitly.
I also notice that after adding the SetParent line, the dialog doesn't always appear in the same place on the window when the program is run, should it not use the coordinates in the dialog definition?
One more thing.. If I specify the dialog coordinates as 0, 0, 100, 100 in the .RC file it appears to display at twice that size. If I then us MoveWindow with the same coordinates the dialog shrinks down to the expected size.
So.. am I missing something, or is this some kind of bug?
Please post the code to confirm if you are doing anything wrong.
P.S.: Dialog coordinates are dependant of the font size you are using in it.
Here's the code, the dialog is at the end.
I took out pretty much everything but the basics. You should see a commented out SetParent line, uncomment it to see the difference.
#define _WIN32_IE 0x0700
#include <windows.h>
LRESULT CALLBACK WindowFunc(HWND, UINT, WPARAM, LPARAM);
BOOL CALLBACK DialogFunc1(HWND, UINT, WPARAM, LPARAM);
char szWinName[] = "MyWin"; /* name of window class */
HINSTANCE hInst;
HWND hwnd;
HWND hDlg = (HWND) NULL;
int WINAPI WinMain(HINSTANCE hThisInst, HINSTANCE hPrevInst,
LPSTR lpszArgs, int nWinMode)
{
MSG msg;
WNDCLASSEX wcl;
/* Define a window class. */
wcl.cbSize = sizeof(WNDCLASSEX);
wcl.hInstance = hThisInst; /* handle to this instance */
wcl.lpszClassName = szWinName; /* window class name */
wcl.lpfnWndProc = WindowFunc; /* window function */
wcl.style = 0; /* default style */
wcl.hIcon = LoadIcon(NULL, IDI_APPLICATION); /* standard icon */
wcl.hIconSm = LoadIcon(NULL, IDI_APPLICATION); /* small icon */
wcl.hCursor = LoadCursor(NULL, IDC_ARROW); /* cursor style */
wcl.lpszMenuName = NULL; /* no main menu */
wcl.cbClsExtra = 0; /* no extra */
wcl.cbWndExtra = 0; /* information needed */
/* Make the window white. */
wcl.hbrBackground = (HBRUSH) GetStockObject(WHITE_BRUSH);
/* Register the window class. */
if(!RegisterClassEx(&wcl)) return 0;
/* Now that a window class has been registered, a window
can be created. */
hwnd = CreateWindowEx(
0,
szWinName, /* name of window class */
"Using a Tab Control", /* title */
WS_OVERLAPPEDWINDOW, /* window style - normal */
CW_USEDEFAULT, /* X coordinate - let Windows decide */
CW_USEDEFAULT, /* Y coordinate - let Windows decide */
CW_USEDEFAULT, /* width - let Windows decide */
CW_USEDEFAULT, /* height - let Windows decide */
HWND_DESKTOP, /* no parent window */
NULL, /* no override of class menu */
hThisInst, /* handle of this instance of the program */
NULL /* no additional arguments */
);
hInst = hThisInst; /* save the current instance handle */
/* Display the window. */
ShowWindow(hwnd, nWinMode);
UpdateWindow(hwnd);
/* Create the message loop. */
while(GetMessage(&msg, NULL, 0, 0))
{
if(!IsDialogMessage(hDlg, &msg)) {
TranslateMessage(&msg); /* translate keyboard messages */
DispatchMessage(&msg); /* return control to Windows 98 */
}
}
return msg.wParam;
}
/* This function is called by Windows 98 and is passed
messages from the message queue.
*/
LRESULT CALLBACK WindowFunc(HWND hwnd, UINT message,
WPARAM wParam, LPARAM lParam)
{
switch(message) {
case WM_CREATE:
hDlg = CreateDialog(hInst, "MyDB1", hwnd,
(DLGPROC) DialogFunc1);
// SetParent(hDlg,hwnd);
// MoveWindow(hDlg, 2, 16, 158, 106, 1);
break;
case WM_PAINT:
break;
case WM_DESTROY: /* terminate the program */
if(hDlg) DestroyWindow(hDlg);
PostQuitMessage(0);
break;
default:
/* Let Windows 98 process any messages not specified in
the preceding switch statement. */
return DefWindowProc(hwnd, message, wParam, lParam);
}
return 0;
}
/* dialog function. */
BOOL CALLBACK DialogFunc1(HWND hdwnd, UINT message,
WPARAM wParam, LPARAM lParam)
{
switch(message) {
case WM_COMMAND:
switch(LOWORD(wParam)) {
case IDOK:
PostQuitMessage(0);
return 1;
}
}
return 0;
}
// this is the dialog file
#include <windows.h>
MyDB1 DIALOG 2, 16, 158, 106
STYLE WS_CHILD | WS_VISIBLE | WS_BORDER
{
}
Well, Mingw uses the Windows system libraries as every other compiler (e.g. VC), so it should behave in the same way regardless of the compiler used.
Why it doesn't work... it's odd to use a dialog to be inserted in a window, but it might be done. Remember that the dialog window created with CreateDialog is independent from the others you created before.
Hope this helped anyway, sorry if not.
Okay thanx, I was pretty much coming to the conclusion that a dialog was not what I need for a tab control even though the example in the book did it that way. I think what I need to use is a static window, haven't tried it yet though.
Basically what I'm trying to do is rewrite a program I did in RapidQ (an object oriented BASIC) in C++.
It's a kind of database that uses a whole bunch of edit controls to input the data, the edits are divided onto the tabs of a tabcontrol. One tab can have up to 128 edits on it, so I need to arrange them all on some kind of parent controls (in RapidQ they have a panel control that I use for this) and then just switch between which parent control is shown when a tab is selected. Hopefully a Static window will work, unless someone else has a better suggestion..