First Steps in Win32

Hi, First of all, I wasn't sure weather to post here or in Windows Programming, As I'm a beginner with this.

I have just started playing with the Win32 API, and following and reading various guides.
Mostly I have been using TheForgers Tutorial and ZetCode and referring to MSDN.

Iv been learning mostly by playing with the examples, and trying to figure it out myself and seem to be making progress. All of the tutorials seem to focus on a single window, so I'v attempted to give myself a program with more than one window. What I want to know, is am I going the right way about it?

The program creates Two windows, each with its of message loop and procedure.

The fist has a button that just changes the title of the first window, the second, is slightly different, it changes the mouse arrow to a hand. I did this so I can visually see that both windows are actually different.

I would just like to have some one look over it. although the program appears to work as intended (It doesn't do much!) I just want to know weather it works because it is correct, or it "Just happens to work". I'm trying to keep it simple to start with. I do find the tutorials get very technical quickly, so some guidance and answering some "Dumb" questions may be required.


The code is as follows

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
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
#include <windows.h>

LRESULT CALLBACK FirstWinProc(HWND, UINT, WPARAM, LPARAM); // First Window Procedure
LRESULT CALLBACK SecondWinProc(HWND, UINT, WPARAM, LPARAM); // Second Window Procedure

HINSTANCE g_hinst;



//Main
int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
                    PWSTR lpCmdLine, int nCmdShow)
{
	

	// Begin Registering the main windows classes
	// fw. First Window. FWmsg is the first window message queue
  MSG  FWmsg;
  WNDCLASSW fw = {0};
  fw.lpszClassName = L"FirstWindow";
  fw.hInstance     = hInstance;
  fw.hbrBackground = GetSysColorBrush(COLOR_3DFACE);
  fw.lpfnWndProc   = FirstWinProc;
  fw.hCursor       = LoadCursor(0, IDC_ARROW);
  
  RegisterClassW(&fw);
  
  //sw. First Window. SWmsg is the Second window message queue
  MSG  SWmsg;
  WNDCLASSW sw = {0};
  sw.lpszClassName = L"SecondWindow";
  sw.hInstance     = hInstance;
  sw.hbrBackground = GetSysColorBrush(COLOR_3DFACE);
  sw.lpfnWndProc   = SecondWinProc;
  sw.hCursor       = LoadCursor(0, IDC_HAND);
  
  RegisterClassW(&sw);
  
  // End of Registering  Window Classes


  CreateWindowW(fw.lpszClassName, L"First Window",  //Display First Window
                WS_OVERLAPPEDWINDOW | WS_VISIBLE,
                  0,  0, 300, 300, 0, 0, hInstance, 0);

  CreateWindowW(sw.lpszClassName, L"Second Window", //Display Second Window
                WS_OVERLAPPEDWINDOW | WS_VISIBLE,
                  300,  0, 300, 300, 0, 0, hInstance, 0);
  
  
  
  // Message Loop For First Window
  while( GetMessage(&FWmsg, NULL, 0, 0)) {
	  TranslateMessage(&FWmsg);
	  DispatchMessage(&FWmsg);
  }
  return (int) FWmsg.wParam;
  
  // Message Loop For Second Window
  while( GetMessage(&SWmsg, NULL, 0, 0)) {
	  TranslateMessage(&SWmsg);
	  DispatchMessage(&SWmsg);
  }
  return (int) SWmsg.wParam;
}





// Window Procedure For First Window
LRESULT CALLBACK FirstWinProc(HWND hwnd, UINT FWinSW, 
    WPARAM wParam, LPARAM lParam)
{    
	 
//Start of First Window Switch FWinSW

  switch(FWinSW)  
  {
	case WM_CREATE:
		CreateWindowW(L"button", L"Change Title",
          WS_VISIBLE | WS_CHILD ,
          20, 50, 100, 25,
          hwnd, (HMENU) 1, NULL, NULL);
		break;


	case WM_CLOSE: 
		PostQuitMessage(0);
		break;
	
	
	case WM_COMMAND:
		 if (LOWORD(wParam) == 1) {
        SetWindowTextW(hwnd, L"Title Changed");
		}
		break;
	
	case WM_DESTROY:
		PostQuitMessage(0);
		break;

  }
  // End of First Window Switch

  

  
  
  return DefWindowProcW(hwnd, FWinSW, wParam, lParam);
}

// End of Window Procedure

// Window Procedure For Second Window   SWinSW
LRESULT CALLBACK SecondWinProc(HWND hwnd, UINT SWinSW, 
    WPARAM wParam, LPARAM lParam)
{    
	 
//Start of Second Window Switch

  switch(SWinSW)  
  {
	case WM_CREATE:
		
		break;


	case WM_CLOSE: 
		PostQuitMessage(0);
		break;
	
	
	case WM_COMMAND:
		
		
		break;
	
	case WM_DESTROY:
		PostQuitMessage(0);
		break;

  }
  // End of Second Window Switch

  

  
  
  return DefWindowProcW(hwnd, SWinSW, wParam, lParam);
}


Between lines 52 and 64, have I correctly guessed that I need 2 separate message loops? and is this implemented correctly?

on lines 19 and 30, what is the {0} for? do these have to have different numbers?

I also assumed I would need two windows procedures, one for each window. Is this also implemented correctly?

Sorry for the questions, but when i search around, the answers i get are extremely complicated, and seem like meaningless drivel to me :(. I just need simple answers to my questions.

Thanks for you'r help

Dave
Last edited on
There is a problem inside WinMain, the second while loop is never executed.
Hi

A assume you mean :

1
2
3
4
5
6
7
8
9
10
11
12
13
// Message Loop For First Window
  while( GetMessage(&FWmsg, NULL, 0, 0)) {
	  TranslateMessage(&FWmsg);
	  DispatchMessage(&FWmsg);
  }
  return (int) FWmsg.wParam;
  
  // Message Loop For Second Window
  while( GetMessage(&SWmsg, NULL, 0, 0)) {
	  TranslateMessage(&SWmsg);
	  DispatchMessage(&SWmsg);
  }
  return (int) SWmsg.wParam;


That thought did cross my mind. How should I form the returns? I assume i have to return values FWmsg.wParam AND SWmsg.wParam . As I mentioned, Iv never come across any example using more than one window.
This thread should be in the windows thread, it's about windows.

Check out the msdn page for getMessage()
http://msdn.microsoft.com/en-us/library/windows/desktop/ms644936%28v=vs.85%29.aspx

The interesting thing is the MSG struct, check it out:
http://msdn.microsoft.com/en-us/library/windows/desktop/ms644958%28v=vs.85%29.aspx

Seems like you don't need two loops (or two MSG structs). The MSG has data about which window the message came from. Since you defined the WndProc of each window to be different, I don't think you will have a problem removing the second loop entirely.

Last edited on
Hi. Apologies for posting in the wrong area. I just wasn't sure

I find the MSDN pages extremely difficult to understand, at times, But you you are saying seems FAR more helpful.

from what i can gather from what you say, i can remove lines 59 through 64 without a problem, as any messages coming in from both windows would be handled by lines 53 to 57? Do I need to change line 29 to match Line 18 (so it uses the same message Queue? Just to clarify?
Last edited on
Thats what I'm saying, but I have no clue really.

Thankyou for the reply. Any other Opinions?
Topic archived. No new replies allowed.