RE: MoveWindow not sending WM_SIZE on deeply nested windows
- From: "Emmanuel Stapf [ES]" <EmmanuelStapfES@xxxxxxxxxxxxxxxxxxxxxxxxx>
- Date: Wed, 21 Dec 2005 14:17:02 -0800
Hi,
I realized that I didn't explain how the two problems will be shown in the
application. The failure to SetParent will be shown through a dialog box
showing the result of the call to GetLastError. And the issue with WM_SIZE is
quite visible, when you resize the top window you should get some nested
rectangle, however you will see that after about a few level the rectangle
gets truncated. The reason is that they are still at their original size
(100x100) and haven't be resized as expected.
Hope this helps,
Manu
--
---------------------------------------------------------
Eiffel Software
http://www.eiffel.com
User group: http://groups.eiffel.com/join
---------------------------------------------------------
"Emmanuel Stapf [ES]" wrote:
> Hi,
>
> I've sent the following message back in June, but at the time I didn't have
> a small example to show you. So below you will find the original message and
> the example showing the problem.
>
> <<
> I found an issue where MoveWindow would not send a WM_SIZE message to the
> window whose size I've requested to change.
>
> To reproduce this, I've setup a window (level 0) with a child (level 1) which
> has another child (level 2), and so on. When I resize `level 0', I get a
> WM_SIZE
> message and I'm calling `MoveWindow' on child at level 1 to resize it, which
> triggers a WM_SIZE message on child at level 1 and I call MoveWindow on
> child at
> level 2 and so on.
>
> It will stop sending the WM_SIZE message at a certain level.
>
> At the same time, I've checked how much nesting I could do and found that at
> level 47, a call to `SetParent' will fail with error code 87 (Parameter being
> incorrect).
>
> Any documentations about the limits of nesting windows? Or workaround for the
> above problems?
> >>
>
> Thanks,
> Manu
>
> ---------------------------------------------------------
> Eiffel Software
> http://www.eiffel.com
> User group: http://groups.eiffel.com/join
> ---------------------------------------------------------
>
>
> #include "windows.h"
>
> HINSTANCE hInst;
> HWND top_window, default_parent; // Top window handle.
> HWND lastHwnd; // Last created window handle
>
> #define szWindowClass "WINDOW"
> #define szTopWindowClass "TOP_WINDOW"
> #define MAX_COUNT 50
> HWND Hwnds[MAX_COUNT];
> int windowCount;
>
> extern LRESULT CALLBACK window_procedure (HWND, UINT, WPARAM, LPARAM);
>
> int find_window (HWND hwnd) {
> int i;
> for (i = 0; i < windowCount; i++) {
> if (hwnd == Hwnds[i]){
> return i;
> }
> }
> i = -1;
> return i;
> }
>
> void display_error () {
> LPVOID lpMsgBuf;
> CHAR szBuf[5120]; DWORD dw = GetLastError();
> FormatMessage(
> FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM |
> FORMAT_MESSAGE_IGNORE_INSERTS,
> NULL,
> dw,
> MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
> (LPTSTR) &lpMsgBuf,
> 0,
> NULL
> );
> sprintf(szBuf, "%s\nGetLastError returned %u\n", lpMsgBuf, dw);
> MessageBox( NULL, szBuf, "Error", MB_OK | MB_ICONINFORMATION );
> LocalFree( lpMsgBuf );
> }
>
> ATOM register_class (LPTSTR a_class)
> {
> WNDCLASSEX wcex;
>
> wcex.cbSize = sizeof(WNDCLASSEX);
>
> wcex.style = CS_HREDRAW | CS_VREDRAW;
> wcex.lpfnWndProc = (WNDPROC)window_procedure ;
> wcex.cbClsExtra = 0;
> wcex.cbWndExtra = 0;
> wcex.hInstance = hInst;
> wcex.hIcon = NULL;
> wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
> wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
> wcex.lpszMenuName = NULL;
> wcex.lpszClassName = a_class;
> wcex.hIconSm = NULL;
>
> return RegisterClassEx(&wcex);
> }
>
> void add_widget ()
> {
> HWND hwnd, last_parent;
>
> hwnd = CreateWindowEx(WS_EX_CONTROLPARENT, szWindowClass, "Child window",
> WS_CHILD | WS_CLIPCHILDREN | WS_CLIPSIBLINGS | WS_VISIBLE,
> 0, 0, 1200, 1200, default_parent, 0, hInst, NULL);
>
> if (!hwnd) {
> display_error ();
> }
> Hwnds[windowCount++]= hwnd;
>
> if (!lastHwnd) {
> last_parent = SetParent (hwnd, top_window);
> } else {
> last_parent = SetParent (hwnd, lastHwnd);
> }
>
> if (!last_parent) {
> display_error ();
> }
>
> MoveWindow (hwnd, 1, 1, 100, 100, 0);
> ShowWindow (hwnd, SW_SHOWDEFAULT);
> UpdateWindow (hwnd);
> lastHwnd = hwnd;
> }
>
> BOOL init ()
> {
> HWND hwnd;
>
> default_parent = CreateWindow(szTopWindowClass, "Test", WS_OVERLAPPEDWINDOW,
> CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInst, NULL);
>
> if (!default_parent) {
> display_error ();
> return FALSE;
> }
>
> top_window = CreateWindow(szTopWindowClass, "Test", WS_OVERLAPPEDWINDOW,
> 0, 0, CW_USEDEFAULT, 0, NULL, NULL, hInst, NULL);
>
> if (!top_window) {
> display_error ();
> return FALSE;
> }
>
> ShowWindow(top_window, SW_SHOW);
> UpdateWindow(top_window);
>
> return TRUE;
> }
>
>
> int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR
> lpCmdLine, int nCmdShow)
> {
> MSG msg;
> int i;
>
> hInst = hInstance;
>
> if (!register_class (szWindowClass)) {
> display_error ();
> return FALSE;
> }
>
> if (!register_class (szTopWindowClass)) {
> display_error ();
> return FALSE;
> }
>
> if (!init ()) {
> display_error ();
> return FALSE;
> }
>
> for (i = 0; i <= MAX_COUNT; i++) {
> add_widget ();
> }
>
> while (GetMessage(&msg, NULL, 0, 0))
> {
> TranslateMessage(&msg);
> DispatchMessage(&msg);
> }
>
> return 0;
> }
>
> void on_size (HWND hwnd) {
> // Search window
> int i;
> RECT r;
>
> // Find child window.
> i = find_window (hwnd) + 1;
>
> // Hwnds [i] might be null when `on_size' is called after creating `hwnd'.
> if (Hwnds [i]) {
> // Got a child!
> GetClientRect (hwnd, &r);
> MoveWindow (Hwnds[i], 1, 1, r.right - r.left - 2, r.bottom - r.top - 2, 0);
> }
> }
>
> LRESULT CALLBACK window_procedure (HWND hwnd, UINT message, WPARAM wParam,
> LPARAM lParam)
> {
> int wmId, wmEvent;
> PAINTSTRUCT ps;
> HDC hdc;
> int i;
>
> switch (message)
> {
> case WM_SIZE:
> on_size (hwnd);
> break;
> case WM_PAINT:
> hdc = BeginPaint(hwnd, &ps);
> i = find_window (hwnd);
> if (i >= 0) {
> if (i % 2 == 0) {
> FillRect (hdc, &ps.rcPaint, (HBRUSH) GetStockObject (GRAY_BRUSH));
> } else {
> FillRect (hdc, &ps.rcPaint, (HBRUSH) GetStockObject (WHITE_BRUSH));
> }
> }
> EndPaint(hwnd, &ps);
> break;
> case WM_DESTROY:
> PostQuitMessage(0);
> break;
> default:
> return DefWindowProc(hwnd, message, wParam, lParam);
> }
> return 0;
> }
>
>
.
- References:
- MoveWindow not sending WM_SIZE on deeply nested windows
- From: Emmanuel Stapf [ES]
- MoveWindow not sending WM_SIZE on deeply nested windows
- Prev by Date: MoveWindow not sending WM_SIZE on deeply nested windows
- Next by Date: Flat progressbar using msctls_progress32
- Previous by thread: MoveWindow not sending WM_SIZE on deeply nested windows
- Next by thread: Flat progressbar using msctls_progress32
- Index(es):
Relevant Pages
|