How to repaint the window with button click?

Pages: 12
I can't seem to understand what I'm doing wrong but it must be something I'm over looking.
I have created two windows, window 1 has the buttons used to control the water level and window 2 are drawn two rectangles, one depicts a tank and the other water in a the tank.

I want the water level to change with the button clicks, So it could look like its filled, half or empty.

I am trying to do this by changing the value of the water level and then redrawing the rectangles but no changes happen.. One problem I see is that the program never enters into any of the if statements in the WM_PAINT section.

I know I am supposed to update the region somehow but I am not sure.

This is my code.

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
152
153
154
155
156
157
158
159
bool Tank_Filled = false;
bool Tank_Empty	= false;
bool Tank_Half_Filled = false;

static int water_Level = 400;

// window 1 and 2 is declared here, both are OVERLAPPED
int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR args, int nCmdShow ){}


// Window Procedure 1
LRESULT CALLBACK WindowProcedure(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp)
{
	switch (msg)
	{
		// Sent when the user selects a command item from a menu, when a control sends a notification message to its parent window, 
		// or when an accelerator keystroke is translated
		case WM_COMMAND:
			switch(wp)
			{
				case IDA_MENU_EXIT:
					DestroyWindow(hWnd);			// PostMessage(hwnd, WM_CLOSE, 0, 0);
					break;
			
				case IDA_MENU_ABOUT:
					displayDialog(hWnd);
					break;
				
				case ID_FILL_TANK:
					water_Level = 80;
					SetWindowText(TextBox, "Filled");
					Tank_Filled = true;
					Tank_Empty = false;
					Tank_Half_Filled = false;
					break;
					
				case ID_EMPTY_TANK:
					water_Level = 525;
					SetWindowText(TextBox, "Empty");
					Tank_Empty = true;
					Tank_Filled = false;
					Tank_Half_Filled = false;
					break;
					
				case ID_HALF_FILL_TANK:
					water_Level = 300;
					SetWindowText(TextBox, "Half-Filled");
					Tank_Half_Filled = true;
					Tank_Filled = false;
					Tank_Empty = false;
					break;
					
				case ID_AUTO_RUN:
					processFile();
					break;
			 
			} // end inner switch
	        
		break;
			
		
		// Sent when an application requests that a window be created by calling the CreateWindowEx or CreateWindow function.
		case WM_CREATE:	
				addControls(hWnd);		
																
			break;
			
		// Sent when a window is being destroyed.
		case WM_DESTROY:
        //	DestroyWindow(g_hToolbar);
			PostQuitMessage(0);
			break;
			
		default:
		
		// The function DefWindowProcW calls the default window procedure to provide default processing for any window messages that an application does not process. 
		// This function ensures that every message is processed.
		return DefWindowProcW(hWnd,msg,wp,lp);
	
	} // end outer switch

} // end

// Window Procedure 2
LRESULT CALLBACK WindowProcedure2(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
	HDC hdc;          	// handle to device context (DC)  
    PAINTSTRUCT ps;   	// paint data for Begin/EndPaint   
    int width,height;  	// Width and height of Client Area
    
    HWND hw;  
  
    switch (msg)  
    {  
	    case WM_CREATE :  
	          
	        return 0;  
	      
	    case WM_SIZE :  
	        width = LOWORD(lParam);  
	        height = HIWORD(lParam);  
	  
	    case WM_PAINT :  
	          
	        hdc = BeginPaint(hWnd, &ps);  
        
	        if(Tank_Filled == true)
			{
				cout << "Filling" << endl;
	        	water_Level = 80;
	        	draw_Tank_Status(hdc, width, height);
	        }	
	        
			if(Tank_Empty == true)
	        	draw_Tank_Status(hdc, width, height);
	        
			if(Tank_Half_Filled == true)
	        	draw_Tank_Status(hdc, width, height);
	  
	        EndPaint(hWnd, &ps);  
	          
	        return 0; 
			 
	    case WM_DESTROY:  
	    case WM_CLOSE :  
	        PostQuitMessage(EXIT_SUCCESS);  
	        return 0;  
	}

    return DefWindowProc(hWnd, msg, wParam, lParam);
}

void draw_Tank_Status(HDC hdc, int width, int height)
{	
    HBRUSH hbrush;  
    HPEN hpen;  

    //draw a rectangle with color blue TANK 
    hpen = CreatePen(PS_SOLID, 4, RGB(0, 51, 51));  
    SelectObject(hdc, hpen);  
    Rectangle(hdc, 160, 80, width - 200, height - 20);  
    DeleteObject(hpen); 
		        
    // Water 
    // Full - 80
    // Half - 300
    // Empty - 525
    
	hpen = CreatePen(PS_SOLID, 4, RGB(51, 255, 255));
	hbrush = CreateSolidBrush(RGB(51, 255, 255));    
    SelectObject(hdc, hpen);  
    SelectObject(hdc, hbrush);  
    Rectangle(hdc, 165, water_Level, width - 205, height - 25);  
    DeleteObject(hbrush); 
    DeleteObject(hpen); 
    
    cout << "Filling" << endl;
}

Last edited on
First thing I think I would do is to call the UpdateWindow() function (documentation found here: https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-updatewindow). Maybe the window gets the message to change the size, but the region needs to be redrawn.

Second thing is to check the WinMain function. Because WM_PAINT is given as a message by the system, I think you would have to do a WM_PRINT message (unless if I am dumb, which I mostly am) to actually be able to draw into WindowProcedure2.

Edit: I don't mean to nitpick here, but why do you have cout << "Filling" << endl; in your draw_Tank_Status() function? WIN32 API does not have a console window to print to and therefore cannot use std::cout or std::cin statement.
Last edited on
Thanks much for responding..

I tried the update function but it doesn't work.

I don't think the WM_PRINT function is used to redraw shapes in the client area.

I used cout << "Filling" << endl; just for testing to see if it ever gets into the function.. But it never does.. I never enters into any of the if statements.
Hmmmmm. May I see the window class registration?
No Problem.

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
int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR args, int nCmdShow )
{
	HWND hwnd;
	MSG Msg 			= {0};

	WNDCLASSEXW wc1  	= {};
	
	wc1.cbSize			= sizeof(WNDCLASSEX);
	wc1.style			= CS_HREDRAW | CS_VREDRAW;
	wc1.hbrBackground 	= (HBRUSH)GetStockObject(WHITE_BRUSH);										 // A handle to the class background brush
	wc1.hCursor 		= LoadCursor(NULL, IDC_ARROW); 										 // A handle to the class cursor. This member must be a handle to a cursor resource. 
	wc1.hInstance 		= hInst;															 // A handle to the instance that contains the window procedure for the class.
	wc1.lpszClassName 	= L"Main Control";												 // A pointer to a null-terminated string or is an atom
	wc1.lpszMenuName 	= MAKEINTRESOURCEW(IDR_SimpleMENU);
	wc1.lpfnWndProc 	= WindowProcedure; 												 // A pointer to the window procedure	
	wc1.cbWndExtra 		= 0;
	wc1.cbClsExtra		= 0;
	wc1.hIcon			= LoadIcon(NULL, IDI_APPLICATION);
	wc1.hIconSm			= LoadIcon(NULL, IDI_APPLICATION);
	
	
	if(!RegisterClassExW(&wc1))
    {
        MessageBox(NULL, "Window Registration Failed!", "Error!", MB_ICONEXCLAMATION | MB_OK);
        std::cout << GetLastError() << '\n'; //or however you want to show it
        return 0;
    }
    
    MainWnd = CreateWindowExW(WS_EX_CLIENTEDGE, wc1.lpszClassName, L"Control", WS_OVERLAPPEDWINDOW | WS_VISIBLE, 20,40,700,600, NULL, NULL, hInst ,NULL );
	
	if(MainWnd == NULL)
    {
        MessageBox(NULL, "Window Creation Failed!", "Error!", MB_ICONEXCLAMATION | MB_OK);
        return 0;
    }
	
	
	WNDCLASSEXW wc2 	= {};

	wc2.cbSize			= sizeof(WNDCLASSEX);
	wc2.style			= CS_HREDRAW | CS_VREDRAW;
//	wc2.hbrBackground 	= (HBRUSH)(COLOR_3DFACE + 12) ;										 // A handle to the class background brush
	wc2.hbrBackground 	= (HBRUSH)GetStockObject(WHITE_BRUSH);										 // A handle to the class background brush
	wc2.hCursor 		= LoadCursor(NULL, IDC_ARROW); 										 // A handle to the class cursor. This member must be a handle to a cursor resource. 
	wc2.hInstance 		= hInst;															 // A handle to the instance that contains the window procedure for the class.
	wc2.lpszClassName 	= L"Water Reservoir";												 // A pointer to a null-terminated string or is an atom
	wc2.lpszMenuName 	= MAKEINTRESOURCEW(IDR_SimpleMENU);
	wc2.lpfnWndProc 	= WindowProcedure2; 												 // A pointer to the window procedure	
	wc2.cbWndExtra 		= 0;
	wc2.cbClsExtra		= 0;
	wc2.hIcon			= LoadIcon(NULL, IDI_APPLICATION);
	wc2.hIconSm			= LoadIcon(NULL, IDI_APPLICATION);
	


	if(!RegisterClassExW(&wc2))
    {
        MessageBox(NULL, "Window Registration Failed!", "Error!", MB_ICONEXCLAMATION | MB_OK);
        std::cout << GetLastError() << '\n'; //or however you want to show it
        return 0;
    }
	
	//CreateWindowExW(WS_EX_CLIENTEDGE, L"Chimney", L"LabOne", WS_CHILD | WS_VISIBLE, 700,40,700,600, MainWnd, NULL, hInst, NULL );
	
	SecdWnd = CreateWindowExW(WS_EX_CLIENTEDGE, wc2.lpszClassName, L"Reservoir", WS_OVERLAPPEDWINDOW | WS_VISIBLE, 800,40,700,600, NULL, NULL, hInst ,NULL );
	
	if(SecdWnd == NULL)
    {
        MessageBox(NULL, "Window Creation Failed!", "Error!", MB_ICONEXCLAMATION | MB_OK);
        return 0;
    }		
	 
	RegisterDialogClass(hInst);														 // Registers any nonstandard window classes required by a screen saver's configuration dialog box.
	
	
	ShowWindow(MainWnd, nCmdShow);
   	UpdateWindow(MainWnd);
	
	ShowWindow(SecdWnd, nCmdShow);
   	UpdateWindow(SecdWnd);
	
	/*
	* Retrieves a message from the calling thread's message queue. 
	* The function dispatches incoming sent messages until a posted message is available for retrieval. 
	*/
	while( GetMessage(&Msg, NULL, 0, 0) > 0)
	{
				TranslateMessage(&Msg);															// Translates virtual-key messages into character messages
		DispatchMessage(&Msg);															// Dispatches a message to a window procedure. 
	}
	
	return 0;
}
Normally you use InvalidateRect to force a repaint of the window, windows will send the WM_PAINT message
https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-invalidaterect
Thannks much for the response Thomas.

Where exactly in the code would I include this the InvalidRect function?

Would it be in the WM_Paint in the WinPro2 or when I make the call to the function WinPro 1?

Please give me some guidance.

BOOL InvalidateRect(HWND hWnd,const RECT *lpRect, BOOL bErase);

I'm Guesing the Rect would be the area i want repaint?
The main thing I see sorta wrong with this is that you have 2 separate window functions that are called within the same function.

Now, I am uncertain if you really need two separate windows (I suggest maybe just use a static control (https://docs.microsoft.com/en-us/windows/win32/controls/static-controls ) without text and has a dynamic height that can be changed while in a conditional or loop that keeps on updating the window). I could provide some code to do that.

But say you do need two separate windows. I don't recommend adding them into the same function to register the classes, as it gets messy. I would instead make the register functions separate and display the second one separate from the first one.

Also, I'd like to add that the UpdateWindow() works on a per call basis, which means that you would have to continuously recall the function. But instead, you've called it once in the register function (and that only happens once, mind you).

So I suggest making a conditional when you need to update the window.
Last edited on
You need to invalidate the second window when you change the water_level in MainWnd
I'm Guesing the Rect would be the area i want repaint? Yes
Hey Kyviro thanks for the response, I will be trying your solution.
Also, the link you sent leads to a 404 error.


Thanks Thomas.. I'm Gonna try your solution first as its simpler.

I've also seen other sources speaking of the same InvalidateRect Function.. I will let you know the results.
The bracket got mixed with the URL; should be fixed now. There you should be able to look at the (kinda unhelpful) documentation.

But you can make static windows by just specifying the class name as "Static".
The main problems is that its just not entering into the if statements in the WM_PAINT section.. I really can't figure out why, probably after i figure it out then I can focus on repainting.
To draw a custom button follow this steps:

1. Create a window with following styles:
WS_CHILD | WS_VISIBLE | BS_OWNERDRAW
and following class name:
L"Button"

2. Now you can handle WM_PAINT in the procedure registered for this button.

Otherwise if you create a button that isn't BS_OWNERDRAW, such as BS_PUSHBUTTON then you need to sublass the button to override WM_PAINT:

1. To subclass a button needed to handle WM_PAINT with
SetWindowSubclass()

2. Now you can handle WM_PAINT in the procedure registered for this button.

3. Any message you do not process pass to:
DefSubclassProc()

4. Before destroying a button (probably during WM_NCDESTROY ) call:
RemoveWindowSubclass()

Note that DefSubclassProc() is used only for sublassed buttons, otherwise use DefWindowProc() for BS_OWNERDRAW
Last edited on
Best way to figure out is to set a breakpoint after line 105hdc = BeginPaint(hWnd, &ps);
Don't forget to call Invalidate Rect inside ID_FILL_TANK, ID_EMPTY_TANK and ID_HALF_FILL_TANK
Hey Thomas,

I did try debugging with the break statement this but it never goes into the if statements..

I printed the boolean values to see if they change but and they do change with every button click as designed.

I did use the invalidaterect fucntion and changed the entire screen but nothing happens..

I am thinking of posting the entire code and Good Samaritan can try it to see whats the problem and suggest a solution.
Hey Malibor,

Thanks much for helping.

I saw your suggestion but I'm not sure if you suggesting that I add BS_OVERDRAW to window 2 in its creation or something.. I understand the steps you want me to make but can you please specify where to make those changes, I'm not a professional yet, So I don't have the High level intuition like you guys lol..

I am gonna post the code in its entirety can you please check it out and recommend changes in ..

That would mean the world to me.
Posting the whole code is a very good idea.
I am sure someone can fix when he can compile and run it.
Don't forget to include the ressource files: *.rc and ressource header

@malibor,
come on. The OP ist struggling with a simple project and you start talking about owner-drawing stuff.
It will just confuse him.
This is the WinMain

Please let me know if anything is missing, I will edit the post.. I use DevC++

I will also like to add that I had to link the following files to the project:
libcomdlg32.a
libgdi32.a

1
2
3
4
5
6
7
8
9
10
11
12
13
// Scada.rc

#include "Scada.h"

IDA_SimpleMENU MENU
BEGIN
    POPUP "&File"
    BEGIN
        MENUITEM "E&xit", IDA_MENU_EXIT
    END
    
    MENUITEM "A&bout", IDA_MENU_ABOUT
END


1
2
3
4
5
6
7
8
9
10
11
12
// Scada.h

#include <windows.h>
#include <Windowsx.h>

#define IDR_SimpleMENU 102
#define IDA_MENU_EXIT 1000
#define IDA_MENU_ABOUT 1001
#define ID_FILL_TANK		200
#define ID_EMPTY_TANK		201
#define ID_HALF_FILL_TANK		202
#define ID_AUTO_RUN				203 


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
// Scada.cpp

///////////// Preprocessors
#include "Scada.h"
#include <string>
#include <iostream>
#include<unistd.h>				// sleep(s) s  -> seconds

using namespace std;


///////////////// Function Prototypes ////////////////////
LRESULT CALLBACK WindowProcedure( HWND, UINT, WPARAM, LPARAM); 
LRESULT CALLBACK WindowProcedure2( HWND, UINT, WPARAM, LPARAM); 
LRESULT CALLBACK DialogProcedure(HWND,UINT, WPARAM, LPARAM);                      // 
void RegisterDialogClass(HINSTANCE);												 //
void displayDialog(HWND);															 //
void AddDialogBox(HWND);
void addControls(HWND);
void draw_Tank_Status(HDC hdc, int width, int height);									 //



// Global Variables:
HWND TextBox;
HWND inputBox;
string inputBoxData;



// Store handles to the main window and application instance globally.
HWND MainWnd = 0;
HWND SecdWnd = 0;


// Shape related Global Variables
bool Tank_Initial_level = true;
bool Tank_Filled	= false;
bool Tank_Empty	= false;
bool Tank_Half_Filled	= false;

static int water_Level = 400;
													 

int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR args, int nCmdShow )
{
	HWND hwnd;
	MSG Msg 			= {0};

	WNDCLASSEXW wc1  	= {};
	
	wc1.cbSize			= sizeof(WNDCLASSEX);
	wc1.style			= CS_HREDRAW | CS_VREDRAW;
	wc1.hbrBackground 	= (HBRUSH)GetStockObject(WHITE_BRUSH);										 // A handle to the class background brush
	wc1.hCursor 		= LoadCursor(NULL, IDC_ARROW); 										 // A handle to the class cursor. This member must be a handle to a cursor resource. 
	wc1.hInstance 		= hInst;															 // A handle to the instance that contains the window procedure for the class.
	wc1.lpszClassName 	= L"Main Control";												 // A pointer to a null-terminated string or is an atom
	wc1.lpszMenuName 	= MAKEINTRESOURCEW(IDR_SimpleMENU);
	wc1.lpfnWndProc 	= WindowProcedure; 												 // A pointer to the window procedure	
	wc1.cbWndExtra 		= 0;
	wc1.cbClsExtra		= 0;
	wc1.hIcon			= LoadIcon(NULL, IDI_APPLICATION);
	wc1.hIconSm			= LoadIcon(NULL, IDI_APPLICATION);
	
	
	if(!RegisterClassExW(&wc1))
    {
        MessageBox(NULL, "Window Registration Failed!", "Error!", MB_ICONEXCLAMATION | MB_OK);
        std::cout << GetLastError() << '\n'; //or however you want to show it
        return 0;
    }
    
    MainWnd = CreateWindowExW(WS_EX_CLIENTEDGE, wc1.lpszClassName, L"Control", WS_OVERLAPPEDWINDOW | WS_VISIBLE, 20,40,700,600, NULL, NULL, hInst ,NULL );
	
	if(MainWnd == NULL)
    {
        MessageBox(NULL, "Window Creation Failed!", "Error!", MB_ICONEXCLAMATION | MB_OK);
        return 0;
    }
	
	
	WNDCLASSEXW wc2 	= {};

	wc2.cbSize			= sizeof(WNDCLASSEX);
	wc2.style			= CS_HREDRAW | CS_VREDRAW;
//	wc2.hbrBackground 	= (HBRUSH)(COLOR_3DFACE + 12) ;										 // A handle to the class background brush
	wc2.hbrBackground 	= (HBRUSH)GetStockObject(WHITE_BRUSH);										 // A handle to the class background brush
	wc2.hCursor 		= LoadCursor(NULL, IDC_ARROW); 										 // A handle to the class cursor. This member must be a handle to a cursor resource. 
	wc2.hInstance 		= hInst;															 // A handle to the instance that contains the window procedure for the class.
	wc2.lpszClassName 	= L"Water Reservoir";												 // A pointer to a null-terminated string or is an atom
	wc2.lpszMenuName 	= MAKEINTRESOURCEW(IDR_SimpleMENU);
	wc2.lpfnWndProc 	= WindowProcedure2; 												 // A pointer to the window procedure	
	wc2.cbWndExtra 		= 0;
	wc2.cbClsExtra		= 0;
	wc2.hIcon			= LoadIcon(NULL, IDI_APPLICATION);
	wc2.hIconSm			= LoadIcon(NULL, IDI_APPLICATION);
	


	if(!RegisterClassExW(&wc2))
    {
        MessageBox(NULL, "Window Registration Failed!", "Error!", MB_ICONEXCLAMATION | MB_OK);
        std::cout << GetLastError() << '\n'; //or however you want to show it
        return 0;
    }
	
	//CreateWindowExW(WS_EX_CLIENTEDGE, L"Chimney", L"LabOne", WS_CHILD | WS_VISIBLE, 700,40,700,600, MainWnd, NULL, hInst, NULL );
	
	SecdWnd = CreateWindowExW(WS_EX_CLIENTEDGE, wc2.lpszClassName, L"Reservoir", WS_OVERLAPPEDWINDOW | WS_VISIBLE, 800,40,700,600, NULL, NULL, hInst ,NULL );
	
	if(SecdWnd == NULL)
    {
        MessageBox(NULL, "Window Creation Failed!", "Error!", MB_ICONEXCLAMATION | MB_OK);
        return 0;
    }		
	 
	RegisterDialogClass(hInst);														 // Registers any nonstandard window classes required by a screen saver's configuration dialog box.
	
	
	ShowWindow(MainWnd, nCmdShow);
   	UpdateWindow(MainWnd);
	
	ShowWindow(SecdWnd, nCmdShow);
   	UpdateWindow(SecdWnd);
	
	/*
	* Retrieves a message from the calling thread's message queue. 
	* The function dispatches incoming sent messages until a posted message is available for retrieval. 
	*/
	while( GetMessage(&Msg, NULL, 0, 0) > 0)
	{
		TranslateMessage(&Msg);															// Translates virtual-key messages into character messages
		DispatchMessage(&Msg);															// Dispatches a message to a window procedure. 
	}
	
	return 0;
}
Last edited on
This is the procedures

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
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
LRESULT CALLBACK WindowProcedure(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp)
{
	RECT rect = {100, 100, 200, 100};
	InvalidateRect(hWnd, &rect, false);

	switch (msg)
	{
		// Sent when the user selects a command item from a menu, when a control sends a notification message to its parent window, 
		// or when an accelerator keystroke is translated
		case WM_COMMAND:
			switch(wp)
			{
				case IDA_MENU_EXIT:
					DestroyWindow(hWnd);			// PostMessage(hwnd, WM_CLOSE, 0, 0);
					break;
			
				case IDA_MENU_ABOUT:
					displayDialog(hWnd);
					break;
				
				case ID_FILL_TANK:
					water_Level = 80;
					SetWindowText(TextBox, "Filled");
					InvalidateRect(hWnd, &rect, false);
					Tank_Filled = true;
					Tank_Empty = false;
					Tank_Half_Filled = false;
					break;
					
				case ID_EMPTY_TANK:
					water_Level = 525;
					SetWindowText(TextBox, "Empty");
					InvalidateRect(hWnd, &rect, false);
					Tank_Empty = true;
					Tank_Filled = false;
					Tank_Half_Filled = false;
					break;
					
				case ID_HALF_FILL_TANK:
					water_Level = 300;
					SetWindowText(TextBox, "Half-Filled");
					InvalidateRect(hWnd, &rect, false);
					Tank_Half_Filled = true;
					Tank_Filled = false;
					Tank_Empty = false;
					break;
					
				case ID_AUTO_RUN:
					
					break;
			 
			} // end inner switch
	        
		break;
			
		
		// Sent when an application requests that a window be created by calling the CreateWindowEx or CreateWindow function.
		case WM_CREATE:	
				addControls(hWnd);		
				HMENU hMenu, hSubMenu;
		
		        hMenu = CreateMenu();
		        hSubMenu = CreatePopupMenu();
			
				// File PopUp Menu
				AppendMenu(hSubMenu,MF_STRING,IDA_MENU_EXIT,"Exit");							// Appends a new item to the end of the specified menu bar, drop-down menu, submenu, or shortcut menu.
				AppendMenu(hMenu, MF_STRING | MF_POPUP, (UINT_PTR)hSubMenu,"File");					//
				
				// About Menu
				AppendMenu(hMenu,MF_STRING,IDA_MENU_ABOUT,"About");						// 
			
				SetMenu(hWnd, hMenu);													// Assigns a new menu to the specified window.
			break;
			
		// Sent when a window is being destroyed.
		case WM_DESTROY:
        //	DestroyWindow(g_hToolbar);
			PostQuitMessage(0);
			break;
			
		default:
		
		// The function DefWindowProcW calls the default window procedure to provide default processing for any window messages that an application does not process. 
		// This function ensures that every message is processed.
		return DefWindowProcW(hWnd,msg,wp,lp);
	
	} // end outer switch

} // end 



LRESULT CALLBACK WindowProcedure2(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
	HDC hdc;          	// handle to device context (DC)  
    PAINTSTRUCT ps;   	// paint data for Begin/EndPaint   
    int width,height;  	// Width and height of Client Area
    
    switch (msg)  
    {  
	    case WM_CREATE :  
	          
	        return 0;  
	      
	    case WM_SIZE :  
	        width = LOWORD(lParam);  
	        height = HIWORD(lParam);  
	  
	    case WM_PAINT :  
	          
	        hdc = BeginPaint(hWnd, &ps);  

//	        draw_Tank_Status(hdc, width, height);
	        
	        Tank_Initial_level = false;
	        
	        if(Tank_Initial_level)
			{
				cout << "Initial Level" << endl;
	        	draw_Tank_Status(hdc, width, height);
	        }
				
	        cout << Tank_Filled << endl;
	        if(Tank_Filled)
			{
				cout << "Filling" << endl;
	        	water_Level = 80;
	        	draw_Tank_Status(hdc, width, height);
	        }	
	        
	        cout << Tank_Empty << endl;
			if(Tank_Empty)
	        {
				cout << "Empty" << endl;
	        	water_Level = 525;
	        	draw_Tank_Status(hdc, width, height);
	        }	
	        
	        cout << Tank_Half_Filled << endl;
			if(Tank_Half_Filled)
	        {
				cout << "Half-Filled" << endl;
	        	water_Level = 300;
	        	draw_Tank_Status(hdc, width, height);
	        }	
	  
	        EndPaint(hWnd, &ps);  
	          
	        return 0; 
			 
	    case WM_DESTROY:  
	    case WM_CLOSE :  
	        PostQuitMessage(EXIT_SUCCESS);  
	        return 0;  
	}

    return DefWindowProc(hWnd, msg, wParam, lParam);
}

void draw_Tank_Status(HDC hdc, int width, int height)
{	
    HBRUSH hbrush;  
    HPEN hpen;  

    //draw a rectangle with color blue TANK 
    hpen = CreatePen(PS_SOLID, 4, RGB(0, 51, 51));  
    SelectObject(hdc, hpen);  
    Rectangle(hdc, 160, 80, width - 200, height - 20);  
    DeleteObject(hpen); 
		        
    // Water 
    // Full - 80
    // Half - 300
    // Empty - 525
    
	hpen = CreatePen(PS_SOLID, 4, RGB(51, 255, 255));
	hbrush = CreateSolidBrush(RGB(51, 255, 255));    
    SelectObject(hdc, hpen);  
    SelectObject(hdc, hbrush);  
    Rectangle(hdc, 165, water_Level, width - 205, height - 25);  
    DeleteObject(hbrush); 
    DeleteObject(hpen); 
    
}
Last edited on
Pages: 12