RE: MoveWindow not sending WM_SIZE on deeply nested windows



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;
> }
>
>
.



Relevant Pages

  • Re: Mouse Position
    ... VOID* pVertices; ... LONG WINAPI wndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM ... HWND CrteWnd(const char *pszName, int x, int y, int w, int h) { ... // Create the application's window ...
    (microsoft.public.win32.programmer.directx.graphics)
  • Re: CDialog minimize topic
    ... I'm calling to my dialog from CMatAgentMFCApp: ... void CMatAgentMFCApp::OnRead ... int cxIcon = GetSystemMetrics; ... If you want to block the parent window you could simple disable ...
    (microsoft.public.vc.mfc)
  • Re: changing bargraph colors
    ... The style is also pretty bad, and you should never "reach inside" a control to draw it as ... int units; ... void CMyControl::SetValues ... // the sum of samples will not fill in the entire window. ...
    (microsoft.public.vc.mfc)
  • Re: Minimal graphics lib for gcc
    ... but the window receives no events. ... void drawOval(int x, int y, int width, int height) { ... You could try glut and the OpenGL tutorials on http://nehe.gamedev.net ...
    (comp.sys.mac.programmer.help)
  • Re: Create Window at Runtime from function
    ... unsigned int input_type; ... * Calculate X position of the Input Window. ... adcInput_GetXPos(void) { ... adcInput_DrawText(HWND hWnd) { ...
    (microsoft.public.vc.mfc)