-
one window, two handles
is there a way to split a singal window to two windows with two handles?
what i mean is: to the user it will look like a singal window, but it will enable me to split the big window into areas, where each area has it's own handle (HWND).
thank you,
-
no, but you can create a bunch of HRGN's and select them into the window's device context as needed.
-
regions would be an interesting approach, depends on what he's trying to do. It seems to me that it would be better to make two windows to start with. Perhaps docked on a parent window. You can set the parent on the fly to undock it. You can always create new windows and move the stuff over.
-
FillYourBrain, I don't really understand what you mean?
can you give me an example please?
-
You could use child windows that would appear to be one continuous window yet contained different handles. This approach would probably resolve what you are trying to do. I am going to post a basic app below that uses 2 child windows that change colors when you click on them. Take note that it appears as if it is one window when the colors match. Additionally their size depends on the main window size, ensuring the illusion.
Code:
#include <windows.h>
#define numChild 2
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
//children window procedure
LRESULT CALLBACK ChildWndProc(HWND, UINT, WPARAM, LPARAM);
TCHAR szChildClass [] = TEXT("Children"); //Child class name
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow) {
static TCHAR szAppName[] = TEXT("ChildWindowDemo");
WNDCLASS wc;
MSG msg;
HWND hwnd;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wc.hInstance = hInstance;
wc.lpfnWndProc = WndProc;
wc.lpszClassName = szAppName;
wc.lpszMenuName = NULL;
wc.style = CS_HREDRAW | CS_VREDRAW;
if(!RegisterClass(&wc)) {
MessageBox(NULL, TEXT("Could not register class"), szAppName, MB_ICONERROR);
return 0;
}
//define and register child window class
wc.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
wc.lpfnWndProc = ChildWndProc;
wc.hIcon = NULL;
wc.lpszClassName = szChildClass;
RegisterClass(&wc);
//-------------------------------------
hwnd = CreateWindow(szAppName,
TEXT("Child Window Demo"),
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
NULL,
NULL,
hInstance,
NULL);
ShowWindow(hwnd, iCmdShow);
UpdateWindow(hwnd);
while(GetMessage(&msg, NULL, 0, 0)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}
LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) {
static HWND hwndChild[numChild]; //create array to hold children
int cxBlock, cyBlock, x;
switch(message) {
case WM_CREATE:
//create our children
for(x = 0; x < numChild; x++) {
hwndChild[x] = CreateWindow(szChildClass,
NULL,
WS_CHILDWINDOW | WS_VISIBLE,
0,
0,
0,
0,
hwnd,
(HMENU)(1 << 8 | x), //child window ID
(HINSTANCE)GetWindowLong(hwnd, GWL_HINSTANCE),
NULL);
}
return 0;
case WM_SIZE:
//each window will be 1/2 width of parent and = height
cxBlock = LOWORD(lParam) / numChild;
cyBlock = HIWORD(lParam);
for(x = 0; x < numChild; x++) {
MoveWindow(hwndChild[x],
x * cxBlock,
0,
cxBlock,
cyBlock,
TRUE);
}
return 0;
case WM_DESTROY:
PostQuitMessage(0);
return 0;
}
return DefWindowProc(hwnd, message, wParam, lParam);
}
LRESULT CALLBACK ChildWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) {
static int iColor;
int bkgColor[4] = {WHITE_BRUSH, LTGRAY_BRUSH, DKGRAY_BRUSH, BLACK_BRUSH};
switch(message) {
case WM_CREATE:
iColor = 0;
SetWindowLong(hwnd, 0, 0);
return 0;
case WM_LBUTTONUP:
SetClassLong(hwnd, GCL_HBRBACKGROUND, (LONG)GetStockObject(bkgColor[iColor]));
InvalidateRect(hwnd, NULL, TRUE);
if(!(iColor == 3)) {
iColor++;
}else {
iColor = 0;
}
return 0;
}
return DefWindowProc(hwnd, message, wParam, lParam);
}
Hope this helps. Happy Coding!!
-
I use a program for my job that is made up of four separate sections. Separating the four sections is a bar that the mouse allows you to resize the four different sections (either horizontally or vertically depending on how that bar stretches across the screen). I was wondering how this was done. The way this program is designed, it seems like the controls are children of the main program. But the controls change location on the screen based on how you resize the different sections.
Is this done using four separate windows (like the example above) or is this done using something like Windows Regions?
Thanks
Tyouk
-
Those resizeable bars are just another type of control used in Windows Forms. I forget what they're called - but they're predefined in the API (I don't recall seeing them in Win32, but at least as early VS.NET they've been there - most likely much earlier.
-
-
andyhunter, your code is exacly what i need, but i don't understand one small thing in your code...
there are two child windows in that main parent one, but only one ChildWndProc, did you mean that this will control both of the child windows?
Code:
//define and register child window class
wc.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
wc.lpfnWndProc = ChildWndProc;
wc.hIcon = NULL;
wc.lpszClassName = szChildClass;
if so, how can i gain more control over the two child windows?
-
Yes, for the above example both child windows shared the same windows callback procedure. You could decide to register a class for each child window and create a seperate windows procedure for each if you wanted them to be seperate.
Another approach is to have the child window procedure send a message to the parent window procedure detailing a message and the child window ID. This way you could also have more control over individual windows.
Happy Coding!!!
-