Child Window Not Processing WM_SIZE

Pages: 12
I have a child window that, for some reason, is not processing the WM_SIZE message, when I use the MoveWindow() function. The position (x, y) changes with MoveWindow(). But the size (nWidth, nHeight) remains the same. From what I can tell, the child window proc is not even receiving a WM_SIZE message.
🔮🧙‍♂️
Probably a problem with one of the dwStyle parameters Anachronon. Not all styles support window sizing. That would add up with the info you provided, i.e., can move window but won't size. Check out both extended styles and regular styles. Likely the problem is in the regular styles.
Thanks Freddie. I have read through all of the regular styles, extended styles, and even the class styles. But, I can find nothing that prevents a window from receiving a WM_SIZE message. Here is the code. Perhaps, you could see something that I am missing. First, the class definition for both the main window and the child window:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
    wndclass.cbSize        = sizeof(wndclass);             //  Register Main Window
    wndclass.style         = CS_HREDRAW | CS_VREDRAW;
    wndclass.lpfnWndProc   = WndProc;
    wndclass.cbClsExtra    = 0;
    wndclass.cbWndExtra    = 0;
    wndclass.hInstance     = hInstance;
    wndclass.hIcon         = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_ICON1));
    wndclass.hCursor       = LoadCursor(NULL, IDC_ARROW);
    wndclass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
    wndclass.lpszMenuName  = MAKEINTRESOURCE(IDR_MENU1);
    wndclass.lpszClassName = szAppName;
    wndclass.hIconSm       = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_ICON1));

    RegisterClassEx(&wndclass);
       
    wndclass.lpfnWndProc   = ImgChildProc;     //  Register Child Window for Image
    wndclass.cbWndExtra    = sizeof(LONG);
    wndclass.hIcon         = NULL;
    wndclass.lpszClassName = L"ImgChild";
    wndclass.hIconSm       = NULL;

    RegisterClassEx(&wndclass);


This is where I create the child window, under the main window's WM_CREATE:

1
2
hImgChild = CreateWindow(L"ImgChild", NULL, WS_CHILD | WS_VISIBLE, 100, 100, 100, 100,
                hWnd, (HMENU)ID_IMG_FRONT, (HINSTANCE)GetWindowLong(hWnd, GWL_HINSTANCE), 0);


Finally, here is code in the main window's WM_SIZE block, where I attempt to change the size of the child window:

 
MoveWindow(hImgChild, 100, 36, 100, 200, TRUE);


The child window moves up to the "36" position. But, the Y size remains at 100. Further, the move of the child from Y=100 to Y=36 leaves a transparent hole in the parent window (I am using the WS_CLIPCHILDREN style on the parent).
Last edited on
I'll test it later when I have a chance Anachronon (tonight), but just a thought off the top of my head...

Do you really need the child window to be a child of the parent? In all the applications I write I tend to make additional 'secondary' windows of the app all 'top level' windows. Don't know if that will affect things or not. Try changing the parent parameter of the CreateWindow("ImgChild",....) to zero and see what happens. I tend to make child windows controls via 'custom controls' or ActiveX Controls.
If I recall correctly, in order to be able to change the size of a window, whether that window be a parent window, or any other kind of window, it needs to be created with either the WS_SIZEBOX or WS_THICKFRAME style. These styles are usually or'ed into some other amalgamation of styles, which is what the WS_OVERLAPPEDWINDOW style is. For example (from MSDN documentation), the WS_OVERLAPPEDWINDOW is this....

 
WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME | WS_MINIMIZEBOX | WS_MAXIMIZEBOX


Note that WS_THICKFRAME is included above. In the case you specified above Anachronon, your child window only has the basic child window control styles of WS_CHILD|WS_VISIBLE. Think for a moment of edit or button window controls on a main window top level form/dialog. Can you resize those? I think not. So I believe you may be able to achieve your desired effect by adding the WS_SIZEBOX style. Let me know if it doesn't work before I start writing code to check it out.

Superfluous, you are working along the same line of thinking that I used, before posting my initial question. You mentioned: "Add a WM_SIZE case to ImgChildProc and add a call to MessageBox to that case." The result: The message box appears when the child's CreateWindow() function is called. However, the message box does NOT appear, when the MoveWindow() function is called. I know that MoveWindow is being called, because the window is being moved--just not resized. Hence, the topic title, "Child Window Not Processing WM_SIZE".
Freddie, neither the WS_SIZEBOX nor the WS_THICKFRAME styles helped. In fact, no change was observed at all.

The child window is essentially meant to be static. It will display a graphic representation of operations performed in the main window. I am using a child because I want it to be scrollable. The resizing is meant to keep the child proportional to changes in the size of the parent, e.g. "MAXIMIZE".
I'll give it some more thought An anachronon. I'd remove any MessageBoxes from the app though that you may be using. They are pure poison for debugging, in my opinion. Realize that their creation, display, and destruction causes messages to be sent to Window Procedures that can badly confound figurring out what's happening.

WM_SIZE messages are sent at the time of object creation and display, so that's part of what you are seeing.


The child window is essentially meant to be static. It will display a graphic representation of operations performed in the main window. I am using a child because I want it to be scrollable. The resizing is meant to keep the child proportional to changes in the size of the parent, e.g. "MAXIMIZE".


I do have a demo, or alternately, a 'proof of concept' program I could post that may be useful to you that operates somewhat like what you are describing above. What the issue with that is I had a large complex program at work that had a button on it something to the effect 'Process Data'. The processing of the data was a long, complex operation that involved reading and writing data to Excel spreadsheets and to reading and writing data to databases on a remote server, and finally producing reports in a MS Word document, so it all could be expected to take some time - like maybe 5 or 10 seconds, up to a minute or so. So a progress bar would be useful. But I wanted to do better than that. What I wanted was something like you described, that is, a continuous update of data processing operations that were taking place, which continuously scrolled as data processing was on going. So I used a 'Worker Thread' for the data processing step, and created another scrollable window to display the ongoing details of all the stuff going on. It all worked out rather well. I'll post it if you want it, although it'll take several posts to provide it all.

I don't recall I had any difficulties with not being able to resize the window as the worker thread was doing its thing. It didn't interfere with any of the outputs. However, I'm quite certain my output window wasn't a child of the parent - simply another top level window with WS_OVERLAPPEDWINDOW style. I seem to recall in my past having to alter the dwStyle parameter of CreateWindow() calls in order to prevent windows from being resized. That's why I thought changing the styles might help. I didn't mention anything about your painting issue. You really have a 2nd issue there.

Here's a full program that creates the child window and it has a sizing border which allows the window to be sized. I don't have time right now to work on it further - maybe tomorrow night. I drug the borders around with the mouse and it worked fine. I couldn't move the window though, likely because it doesn't have a style with a caption bar which would allow the window to be drug. I can try later; gotta go to bed now.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
// Main.cpp
// cl Main.cpp /O1 /Os /GS- /FeTest.exe /link TCLib.lib kernel32.lib user32.lib gdi32.lib
// cl Main.cpp /O1 /Os /GS- /FeTest.exe /link kernel32.lib user32.lib gdi32.lib
#include <windows.h>
#define IDC_SHOW_OUTPUT   2000
#define IDC_EXIT          2005


LRESULT CALLBACK fnOutputScreenProc(HWND hWnd, unsigned int msg, WPARAM wParam, LPARAM lParam)
{ 
 return (DefWindowProc(hWnd, msg, wParam, lParam));
}


LRESULT CALLBACK fnWndProc(HWND hWnd, unsigned int msg, WPARAM wParam, LPARAM lParam)
{ 
 switch(msg)
 {
   case WM_CREATE:
    {
        HINSTANCE hIns=NULL;
        WNDCLASSEX wc;
        hIns=((LPCREATESTRUCT)lParam)->hInstance;
        SetWindowLongPtr(hWnd,0,(LONG_PTR)hIns);
        wc.lpszClassName = "Output_Screen",   wc.lpfnWndProc   = fnOutputScreenProc;
        wc.hInstance     = hIns,              wc.style         = CS_DBLCLKS;
        wc.cbClsExtra    = 0,                 wc.cbWndExtra    = sizeof(void*);
        wc.lpszMenuName  = NULL,              wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
        wc.hIcon         = (HICON)LoadImage(NULL, IDI_APPLICATION, IMAGE_ICON, 0, 0, LR_DEFAULTCOLOR);
        wc.hIconSm       = (HICON)LoadImage(NULL, IDI_APPLICATION, IMAGE_ICON, 0, 0, LR_DEFAULTCOLOR);
        wc.hCursor       = (HCURSOR)LoadImage(NULL, IDC_ARROW, IMAGE_CURSOR, 0, 0, LR_SHARED);
        wc.cbSize        = sizeof(wc);
        ATOM bReturn=RegisterClassEx(&wc);
        CreateWindow("button","Show Output Screen",WS_CHILD|WS_VISIBLE,75,175,160,35,hWnd,(HMENU)IDC_SHOW_OUTPUT,hIns,0);
        
        return 0;
    }
   case WM_COMMAND:
    {
        if(LOWORD(wParam)==IDC_SHOW_OUTPUT && HIWORD(wParam)==BN_CLICKED)
        {
           HINSTANCE hIns=(HINSTANCE)GetWindowLongPtr(hWnd,0);
           HWND hOutput=CreateWindowEx(WS_EX_WINDOWEDGE,"Output_Screen","Output Screen",WS_CHILD|WS_VISIBLE|WS_SIZEBOX|WS_BORDER,10,10,200,60,hWnd,(HMENU)0,hIns,0);            
        }   
        return 0;
    }   
   case WM_DESTROY:
    {
        PostQuitMessage(0);
        return 0;
    }
 }
 
 return (DefWindowProc(hWnd, msg, wParam, lParam));
}
 
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevIns, LPSTR lpszArgument, int iShow)
{
 MSG messages;
 WNDCLASS wc;
  
 wc.lpszClassName = "Form1",   wc.lpfnWndProc   = fnWndProc;
 wc.hInstance     = hInstance, wc.style         = 0;
 wc.cbClsExtra    = 0,         wc.cbWndExtra    = sizeof(void*);
 wc.hIcon         = NULL,      wc.hCursor       = NULL;
 wc.lpszMenuName  = NULL,      wc.hbrBackground = (HBRUSH)GetStockObject(LTGRAY_BRUSH);
 RegisterClass(&wc);
 CreateWindow("Form1","Form1",WS_OVERLAPPEDWINDOW|WS_VISIBLE,200,100,325,300,HWND_DESKTOP,0,hInstance,0);
 while(GetMessage(&messages,NULL,0,0))
 {
    TranslateMessage(&messages);
    DispatchMessage(&messages);
 }

 return messages.wParam;
}


None of this addresses your painting problem - only window sizing.
I added the WS_CAPTION style so now the child window for output I guess has the WS_SIZEBOX style and the WS_CAPTION style, in addition to WS_CHILD and WS_VISIBLE, so now it can be both resized and moved within the client area of the main window. Note that if you want to respond to WM_SIZE messages that code needs to be within the Window Procedure of the child window. Alternately, if you want to resize the child window as the main window is being resized, then intercept WM_SIZE messages within the main window, and execute MoveWindow() calls there using the HWND of the child as the 1st parameter of MoveWindow() call...

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
// Main.cpp
// cl Main.cpp /O1 /Os /GS- /FeTest.exe /link TCLib.lib kernel32.lib user32.lib gdi32.lib
// cl Main.cpp /O1 /Os /GS- /FeTest.exe /link kernel32.lib user32.lib gdi32.lib
#include <windows.h>  // 2,560 Bytes Exe Size
#define IDC_SHOW_OUTPUT   2000
#define IDC_MOVE_WINDOW   2005
#define IDC_EXIT          2010
#define IDC_OUTPUT        2015


LRESULT CALLBACK fnOutputScreenProc(HWND hWnd, unsigned int msg, WPARAM wParam, LPARAM lParam)
{ 
 return (DefWindowProc(hWnd, msg, wParam, lParam));
}


LRESULT CALLBACK fnWndProc(HWND hWnd, unsigned int msg, WPARAM wParam, LPARAM lParam)
{ 
 switch(msg)
 {
   case WM_CREATE:
    {
        HINSTANCE hIns=NULL;
        WNDCLASSEX wc;
        hIns=((LPCREATESTRUCT)lParam)->hInstance;
        SetWindowLongPtr(hWnd,0,(LONG_PTR)hIns);
        wc.lpszClassName = "Output_Screen",   wc.lpfnWndProc   = fnOutputScreenProc;
        wc.hInstance     = hIns,              wc.style         = CS_DBLCLKS;
        wc.cbClsExtra    = 0,                 wc.cbWndExtra    = sizeof(void*);
        wc.lpszMenuName  = NULL,              wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
        wc.hIcon         = (HICON)LoadImage(NULL, IDI_APPLICATION, IMAGE_ICON, 0, 0, LR_DEFAULTCOLOR);
        wc.hIconSm       = (HICON)LoadImage(NULL, IDI_APPLICATION, IMAGE_ICON, 0, 0, LR_DEFAULTCOLOR);
        wc.hCursor       = (HCURSOR)LoadImage(NULL, IDC_ARROW, IMAGE_CURSOR, 0, 0, LR_SHARED);
        wc.cbSize        = sizeof(wc);
        ATOM bReturn=RegisterClassEx(&wc);
        CreateWindow("button","Show Output Screen",WS_CHILD|WS_VISIBLE,210,200,180,35,hWnd,(HMENU)IDC_SHOW_OUTPUT,hIns,0);
        CreateWindow("button","Move Output Screen",WS_CHILD|WS_VISIBLE,210,250,180,35,hWnd,(HMENU)IDC_MOVE_WINDOW,hIns,0);
        
        return 0;
    }
   case WM_COMMAND:
    {
        switch(LOWORD(wParam))
        {
           case IDC_SHOW_OUTPUT:
            {
                CreateWindowEx
                (
                 WS_EX_WINDOWEDGE,
                 "Output_Screen",
                 "Output Screen",
                 WS_CHILD|WS_VISIBLE|WS_SIZEBOX|WS_BORDER|WS_CAPTION,
                 10,10,200,100,
                 hWnd,
                 (HMENU)IDC_OUTPUT,
                 (HINSTANCE)GetWindowLongPtr(hWnd,0),
                 0
                );
                break;
            }
           case IDC_MOVE_WINDOW:
            {
                MoveWindow(GetDlgItem(hWnd,IDC_OUTPUT),20,450,300,100,TRUE);
                break;
            }         
        } 
        return 0;
    }   
   case WM_DESTROY:
    {
        PostQuitMessage(0);
        return 0;
    }
 }
 
 return (DefWindowProc(hWnd, msg, wParam, lParam));
}

 
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevIns, LPSTR lpszArgument, int iShow)
{
 MSG messages;
 WNDCLASS wc;
  
 wc.lpszClassName = "Form1",   wc.lpfnWndProc   = fnWndProc;
 wc.hInstance     = hInstance, wc.style         = 0;
 wc.cbClsExtra    = 0,         wc.cbWndExtra    = sizeof(void*);
 wc.hIcon         = NULL,      wc.hCursor       = NULL;
 wc.lpszMenuName  = NULL,      wc.hbrBackground = (HBRUSH)GetStockObject(LTGRAY_BRUSH);
 RegisterClass(&wc);
 CreateWindow("Form1","Form1",WS_OVERLAPPEDWINDOW|WS_VISIBLE,100,100,625,600,HWND_DESKTOP,0,hInstance,0);
 while(GetMessage(&messages,NULL,0,0))
 {
    TranslateMessage(&messages);
    DispatchMessage(&messages);
 }

 return messages.wParam;
}
Last edited on
So I really don't understand why you say it isn't working Anachronon. Seems to me to be working as I expected????
I don't understand either. I have the MoveWindow() function in the parent window's WM_SIZE block. The MoveWindow() function is executing, as I can the the origin of the child window shift. But, the child window is not receiving or processing the new size posted in MoveWindow(). It makes no sense.

I have thought of trying to use SetWindowPos(), to see if that works. But, I cannot figure-out the flags used in that function.

In the main window, I am using a custom menu widget that I designed. Could this somehow be interfering? I don't see how, as it only works on the main window.

Though I have been working on this project for a year now, I am on the verge of just giving-up. It has been an endless fight with windows, with no end in sight.

I have a child window that, for some reason, is not processing the WM_SIZE message, when I use the MoveWindow() function. The position (x, y) changes with MoveWindow(). But the size (nWidth, nHeight) remains the same. From what I can tell, the child window proc is not even receiving a WM_SIZE message.


One thing about the WM_SIZE message that I've seen folks misunderstand is that the message isn't functional in terms of resizing the window - it's functionality is strictly in terms of a reporting mechanism, the report coming in through the parameters of the call, i.e., wParam and lParam. To be perfectly honest, I wouldn't bet my life a window will receive a WM_SIZE message as a result of a MoveWindow() or SetWindowPos() call. Like so much of this stuff, one can't be sure one thing or another will happen until one tests it in a test app. When I have a chance I'll test it using my above code. I think these calls will cause a WM_SIZE message, but, like I said, I wouldn't bet my life on it.

But what you are trying to do, if I understand you correctly, is immently doable. Not particularly easy, but doable. Just a thought...

When I put together the last app I posted above, where I could programatically, or with the mouse, move and resize the child window around inside the parent window, it reminded me of Microsoft's MDI (Multiple Document Interface) technology, which is sometimes understood in contradistinction to SDI (Single Document Interface) architectures. Examples of this coding paradigm would be a lot of word processors where a lot of different documents can b e loaded at one time and one can switch between them, e.g, MS Word. I studied these architectures in detail but never used them in any of my apps at work, or even for pleasure for that matter. The Forger's Win32 Tutorials had a good segment on them, and Charles Petzold had an example in his books.

But that last program above seems to be doing what you say you can't get your app to do? Couldn't you use mine to figure out what's going wrong in yours? And that painting problem you are having, mine above seems to be working OK.

I'm with you on SetWindowPos(). Makes me shudder! I've successfully used it in a number of apps, but I always dread when things deteriorate to the point where I need to start thinking about trying to get things working with that miserable function.
Thanks Freddie. I have played with it a bit, tested your code, and I found something interesting. Because my child window is virtually "static", it does not receive a WM_SIZE message (other than upon initial creation). So, I moved all calculations on resizing to the WM_PAINT block. The child window now works as it should.

Which, brings up another strange issue. For some reason, my child window is coming out transparent. I need to use the FillRgn() function in the child's WM_PAINT, to make that window visible. Is that normal? Yes, I do have WS_VISIBLE in the styles.
What do you mean by 'static' Anachronon? That has me confused.

Anyway, today late before I checked back here I finished another version of the programm posted above where I got rid of the buttons and just have the main blank window, and the child window positioned at upper left. I added WM_SIZE handler code to the main window, and as one resizes the main window by dragging the border, in the WM_SIZE handler I put MoveWindow() calls on the child window which increments/decrements its size as the main window gets bigger, smaller, whatever. Had fun doing it. Never did anything quite like that before. Anyway, here it is....

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
// Main.cpp
// cl Main.cpp /O1 /Os /GS- /FeTest.exe /link crt_win_a.obj memset.obj kernel32.lib user32.lib gdi32.lib  // 4,096 Bytes VS 2008; 4,608 Bytes VS 2019
// cl Main.cpp /O1 /Os /GS- /FeTest.exe /link kernel32.lib user32.lib gdi32.lib  // 92,672 Bytes LIBC.lib
#include <windows.h>  
//#include "memory.h"
#define IDC_EXIT    2000
#define IDC_OUTPUT  2005


LRESULT CALLBACK fnOutputScreenProc(HWND hWnd, unsigned int msg, WPARAM wParam, LPARAM lParam)
{ 
 return (DefWindowProc(hWnd, msg, wParam, lParam));
}


LRESULT CALLBACK fnWndProc(HWND hWnd, unsigned int msg, WPARAM wParam, LPARAM lParam)
{ 
 switch(msg)
 {
   case WM_CREATE:
    {
        HINSTANCE  hIns    = NULL;
        HWND       hOutput = NULL;
        WNDCLASSEX wc;
        
        hIns=((LPCREATESTRUCT)lParam)->hInstance;
        SetWindowLongPtr(hWnd,0,(LONG_PTR)hIns);
        wc.lpszClassName = "Output_Screen",   wc.lpfnWndProc   = fnOutputScreenProc;
        wc.hInstance     = hIns,              wc.style         = CS_DBLCLKS;
        wc.cbClsExtra    = 0,                 wc.cbWndExtra    = sizeof(void*);
        wc.lpszMenuName  = NULL,              wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
        wc.hIcon         = (HICON)LoadImage(NULL, IDI_APPLICATION, IMAGE_ICON, 0, 0, LR_DEFAULTCOLOR);
        wc.hIconSm       = (HICON)LoadImage(NULL, IDI_APPLICATION, IMAGE_ICON, 0, 0, LR_DEFAULTCOLOR);
        wc.hCursor       = (HCURSOR)LoadImage(NULL, IDC_ARROW, IMAGE_CURSOR, 0, 0, LR_SHARED);
        wc.cbSize        = sizeof(wc);
        RegisterClassEx(&wc);
        hOutput=CreateWindowEx
        (
          WS_EX_WINDOWEDGE,
          "Output_Screen",
          "Output Screen",
          WS_CHILD|WS_VISIBLE|WS_SIZEBOX|WS_BORDER|WS_CAPTION,
          0,0,200,100,
          hWnd,
          (HMENU)IDC_OUTPUT,
          (HINSTANCE)GetWindowLongPtr(hWnd,0),
          0
        );
        if(hOutput)
           SetWindowLongPtr(hWnd,1*sizeof(void*),(LONG_PTR)hOutput);
               
        return 0;
    }
   case WM_SIZE:
    {
        HWND hOutput=NULL;
        RECT rc;
        
        memset(&rc,0,sizeof(rc));
        GetClientRect(hWnd,&rc);
        int iXDiff = rc.right  - 625;
        int iYDiff = rc.bottom - 600;
        hOutput=(HWND)GetWindowLongPtr(hWnd,1*sizeof(void*));
        if(hOutput)
        { 
           memset(&rc,0,sizeof(rc));
           GetClientRect(hOutput,&rc);
        }
        MoveWindow(GetDlgItem(hWnd,IDC_OUTPUT),10,10,200+iXDiff,100+iYDiff,TRUE);
               
        return 0; 
    }   
   case WM_DESTROY:
    {
        PostQuitMessage(0);
        return 0;
    }
 }
 
 return (DefWindowProc(hWnd, msg, wParam, lParam));
}
 
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevIns, LPSTR lpszArgument, int iShow)
{
 MSG messages;
 WNDCLASS wc;
  
 wc.lpszClassName = "Form1",   wc.lpfnWndProc   = fnWndProc;
 wc.hInstance     = hInstance, wc.style         = 0;
 wc.cbClsExtra    = 0,         wc.cbWndExtra    = 2*sizeof(void*);
 wc.hIcon         = NULL,      wc.hCursor       = NULL;
 wc.lpszMenuName  = NULL,      wc.hbrBackground = (HBRUSH)GetStockObject(LTGRAY_BRUSH);
 RegisterClass(&wc);
 CreateWindow("Form1","Form1",WS_OVERLAPPEDWINDOW|WS_VISIBLE,100,100,625,600,HWND_DESKTOP,0,hInstance,0);
 while(GetMessage(&messages,NULL,0,0))
 {
    TranslateMessage(&messages);
    DispatchMessage(&messages);
 }

 return messages.wParam;
}


Perhaps tomorrow I can address your other question.

Fred
By static, I am saying the the window will not receive or process any mouse or keyboard input, and will never receive "focus". It will merely be a graphic display, showing the calculations being done in the main window.

Thanks Freddie. The code that I used is fairly similar. What I found interesting (and confusing) was that the child window itself, does not receive a WM_SIZE message when the size is changed. For example, in your code, all calculations within fnOutputScreenProc(), relating to the change of size (like GetClientRect) need to be done within WM_PAINT.
In my code above fnOutputScreenProc() does receive any/all messages pertaining to it. I had verified this with a log file as in one of my examples above.

I didn't do any calculations in fnOutputScreenProc(). Its an empty function except for the call to DefWindowProc()....

1
2
3
4
LRESULT CALLBACK fnOutputScreenProc(HWND hWnd, unsigned int msg, WPARAM wParam, LPARAM lParam)
{ 
 return (DefWindowProc(hWnd, msg, wParam, lParam));
}


But as I said above, it is receiving WM_SIZE message. If you doubt this, put some output statements in it.
Been wondering why your code doesn't receive WM_SIZE messages in the child window. So I tested mine again and put fprintf() calls to a log file in both the main window and the child window. When one drags the border of the main window WM_SIZE messages are sent to both windows, as, of course, there are MoveWindow() calls to the child in the parent's WM_SIZE code. Here is an abbridged version of the log file....

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
Entering fnWndProc() - WM_CREATE
  hWnd = Ox00000000001E027C
  Entering fnOutputScreenProc() - WM_SIZE
    rc.left   = 0
    rc.right  = 184
    rc.top    = 0
    rc.bottom = 62
  Leaving fnOutputScreenProc() - WM_SIZE
Leaving fnWndProc() - WM_CREATE

Entering fnWndProc() - WM_SIZE
  Entering fnOutputScreenProc() - WM_SIZE
    rc.left   = 0
    rc.right  = 168
    rc.top    = 0
    rc.bottom = 24
  Leaving fnOutputScreenProc() - WM_SIZE
Leaving fnWndProc() - WM_SIZE

Entering fnWndProc() - WM_SIZE
  Entering fnOutputScreenProc() - WM_SIZE
    rc.left   = 0
    rc.right  = 168
    rc.top    = 0
    rc.bottom = 25
  Leaving fnOutputScreenProc() - WM_SIZE
Leaving fnWndProc() - WM_SIZE

.....
.....
.....


Entering fnWndProc() - WM_SIZE
  Entering fnOutputScreenProc() - WM_SIZE
    rc.left   = 0
    rc.right  = 192
    rc.top    = 0
    rc.bottom = 48
  Leaving fnOutputScreenProc() - WM_SIZE
Leaving fnWndProc() - WM_SIZE

Entering fnWndProc() - WM_DESTROY
  hWnd = Ox00000000001E027C
Leaving fnWndProc() - WM_DESTROY


Here's the modified code with fprintfs...

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
// Main.cpp
// cl Main.cpp /O1 /Os /GS- /FeTest.exe /link crt_win_a.obj memset.obj kernel32.lib user32.lib gdi32.lib  // 4,096 Bytes
// cl Main.cpp /O1 /Os /GS- /FeTest.exe /link TCLib.lib kernel32.lib user32.lib gdi32.lib
// cl Main.cpp /O1 /Os /GS- /FeTest.exe /link kernel32.lib user32.lib gdi32.lib
// #define TCLib
#include <windows.h> 
#ifdef TCLib
   #include "stdio.h"
#else
   #include <stdio.h>
#endif  
//#include "memory.h"
#define IDC_OUTPUT  2005
FILE* fp=NULL;


LRESULT CALLBACK fnOutputScreenProc(HWND hWnd, unsigned int msg, WPARAM wParam, LPARAM lParam)
{
 if(msg==WM_SIZE)
 {
    RECT rc;
    
    fprintf(fp,"  Entering fnOutputScreenProc() - WM_SIZE\n");
    memset(&rc,0,sizeof(rc));
    GetClientRect(hWnd,&rc);
    fprintf(fp,"    rc.left   = %d\n",rc.left);
    fprintf(fp,"    rc.right  = %d\n",rc.right);
    fprintf(fp,"    rc.top    = %d\n",rc.top);
    fprintf(fp,"    rc.bottom = %d\n",rc.bottom);
    fprintf(fp,"  Leaving fnOutputScreenProc() - WM_SIZE\n");
    return 0;
 }
 
 return (DefWindowProc(hWnd, msg, wParam, lParam));
}


LRESULT CALLBACK fnWndProc(HWND hWnd, unsigned int msg, WPARAM wParam, LPARAM lParam)
{ 
 switch(msg)
 {
   case WM_CREATE:
    {
        HINSTANCE  hIns    = NULL;
        HWND       hOutput = NULL;
        WNDCLASSEX wc;
        
        fp=fopen("Output.txt","w");  
        fprintf(fp,"Entering fnWndProc() - WM_CREATE\n");
        fprintf(fp,"  hWnd = Ox%p\n",hWnd);    
        hIns=((LPCREATESTRUCT)lParam)->hInstance;
        SetWindowLongPtr(hWnd,0,(LONG_PTR)hIns);
        wc.lpszClassName = "Output_Screen",   wc.lpfnWndProc   = fnOutputScreenProc;
        wc.hInstance     = hIns,              wc.style         = CS_DBLCLKS;
        wc.cbClsExtra    = 0,                 wc.cbWndExtra    = sizeof(void*);
        wc.lpszMenuName  = NULL,              wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
        wc.hIcon         = (HICON)LoadImage(NULL, IDI_APPLICATION, IMAGE_ICON, 0, 0, LR_DEFAULTCOLOR);
        wc.hIconSm       = (HICON)LoadImage(NULL, IDI_APPLICATION, IMAGE_ICON, 0, 0, LR_DEFAULTCOLOR);
        wc.hCursor       = (HCURSOR)LoadImage(NULL, IDC_ARROW, IMAGE_CURSOR, 0, 0, LR_SHARED);
        wc.cbSize        = sizeof(wc);
        RegisterClassEx(&wc);
        hOutput=CreateWindowEx
        (
          WS_EX_WINDOWEDGE,
          "Output_Screen",
          "Output Screen",
          WS_CHILD|WS_VISIBLE|WS_SIZEBOX|WS_BORDER|WS_CAPTION,
          0,0,200,100,
          hWnd,
          (HMENU)IDC_OUTPUT,
          (HINSTANCE)GetWindowLongPtr(hWnd,0),
          0
        );
        if(hOutput)
           SetWindowLongPtr(hWnd,1*sizeof(void*),(LONG_PTR)hOutput);
        fprintf(fp,"Leaving fnWndProc() - WM_CREATE\n\n");  
               
        return 0;
    }
   case WM_SIZE:
    {
        HWND hOutput=NULL;
        RECT rc;
        
        fprintf(fp,"Entering fnWndProc() - WM_SIZE\n");
        memset(&rc,0,sizeof(rc));
        GetClientRect(hWnd,&rc);
        int iXDiff = rc.right  - 625;
        int iYDiff = rc.bottom - 600;
        hOutput=(HWND)GetWindowLongPtr(hWnd,1*sizeof(void*));
        if(hOutput)
        { 
           memset(&rc,0,sizeof(rc));
           GetClientRect(hOutput,&rc);
        }
        MoveWindow(GetDlgItem(hWnd,IDC_OUTPUT),10,10,200+iXDiff,100+iYDiff,TRUE);
        fprintf(fp,"Leaving fnWndProc() - WM_SIZE\n\n");       
        return 0; 
    }   
   case WM_DESTROY:
    {
        fprintf(fp,"Entering fnWndProc() - WM_DESTROY\n");
        fprintf(fp,"  hWnd = Ox%p\n",hWnd);
        PostQuitMessage(0);
        fprintf(fp,"Leaving fnWndProc() - WM_DESTROY\n");
        fclose(fp);
        
        return 0;
    }
 }
 
 return (DefWindowProc(hWnd, msg, wParam, lParam));
}
 
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevIns, LPSTR lpszArgument, int iShow)
{
 MSG messages;
 WNDCLASS wc;
  
 wc.lpszClassName = "Form1",   wc.lpfnWndProc   = fnWndProc;
 wc.hInstance     = hInstance, wc.style         = 0;
 wc.cbClsExtra    = 0,         wc.cbWndExtra    = 2*sizeof(void*);
 wc.hIcon         = NULL,      wc.hCursor       = NULL;
 wc.lpszMenuName  = NULL,      wc.hbrBackground = (HBRUSH)GetStockObject(LTGRAY_BRUSH);
 RegisterClass(&wc);
 CreateWindow("Form1","Form1",WS_OVERLAPPEDWINDOW|WS_VISIBLE,100,100,625,600,HWND_DESKTOP,0,hInstance,0);
 while(GetMessage(&messages,NULL,0,0))
 {
    TranslateMessage(&messages);
    DispatchMessage(&messages);
 }

 return messages.wParam;
}


Now I want to check and see what happens if I remove the WS_SIZEBOX and/or WS_CAPTION styles from the child window's dwStyle parameter. I expect it'll break the app. We'll see.....
Last edited on
Just tested that. I removed the WS_BORDER, WS_SIZEBOX and the WS_CAPTION styles, and the app still works as above. Well, missing new member superflous was so incensed by my posts that he had to jump in to say I was full of s***. He was right after all. I am full of s***, much to my dismay. So I really don't have any idea why you aren't seeing WM_SIZE messages Anachronon.
Pages: 12