Thread: More Windows Trouble

  1. #1
    Registered User samGwilliam's Avatar
    Join Date
    Feb 2002
    Location
    Newport
    Posts
    382

    More Windows Trouble

    OK, I close the window but the process doesn't go away - it stays there and has to be manually shut down. I am calling DestroyWindow, too.
    Last edited by samGwilliam; 04-12-2005 at 05:42 AM.
    Current Setup: Win 10 with Code::Blocks 17.12 (GNU GCC)

  2. #2
    Registered User samGwilliam's Avatar
    Join Date
    Feb 2002
    Location
    Newport
    Posts
    382
    Also, what's the WM_ event for when the window gets the focus. I got it so it redraws when you move or resize but if it goes behind another window then goes back in front it won't redraw.
    Current Setup: Win 10 with Code::Blocks 17.12 (GNU GCC)

  3. #3
    Registered User samGwilliam's Avatar
    Join Date
    Feb 2002
    Location
    Newport
    Posts
    382
    OK now I got another problem: at first, just to test things out I had a message box come up on WM_CREATE. After I got my game of life working I decided to take this message box out. All of a sudden I just get a window full of black. Commenting out a MessageBox statement has altered the entire logic of the program or something.

    I swear Windows programming is the most ridiculous, frustrating, arcane and downright stupid thing I have ever come across. I mean you couldn't make it up. What a pile of crap.
    Current Setup: Win 10 with Code::Blocks 17.12 (GNU GCC)

  4. #4
    Chief Code Coloniser!
    Join Date
    Apr 2005
    Posts
    121
    WM_ACTIVATE is the message you need to have a look at for window activation, and WM_PAINT is the message you need to handle for redrawing.

    To make sure that your process exits when you destroy the window, make sure you call PostQuitMessage(). Providing you have the correct checking in your message pump, your thread should end.

    Cheers.

  5. #5
    Chief Code Coloniser!
    Join Date
    Apr 2005
    Posts
    121
    Hrm, sounds quite strange to me. Perhaps you could upload your code for us to check out ?

    cheers.

  6. #6
    Registered User samGwilliam's Avatar
    Join Date
    Feb 2002
    Location
    Newport
    Posts
    382
    Here's the entire code (with message commented out):

    Code:
    #include <windows.h>
    
    #define MAX 300
    
    LRESULT CALLBACK MainWindowProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
    
    int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
    {
    	WNDCLASS myWin;
    	MSG msg;
    
    	myWin.style = CS_VREDRAW | CS_HREDRAW;
    	myWin.lpfnWndProc = MainWindowProc;
    	myWin.cbClsExtra = 0;
    	myWin.cbWndExtra = 0;
    	myWin.hInstance = hInstance;
    	myWin.hIcon = LoadIcon (NULL, IDI_APPLICATION);
    	myWin.hCursor = LoadCursor (NULL, IDC_ARROW);
    	myWin.hbrBackground = (HBRUSH) (COLOR_SCROLLBAR + 1);
    	myWin.lpszMenuName = 0;
    	myWin.lpszClassName = "My First App.";
    
    	
    	if (!RegisterClass (&myWin))
    		return 0;
    
    	HWND hwnd;
    
    	hwnd = CreateWindow (	"My First App.",
    							"SamLife, v1.0",
    							WS_OVERLAPPEDWINDOW,
    							20,
    							20,
    							MAX + 40,
    							MAX + 60,
    							NULL,
    							NULL,
    							hInstance,
    							NULL);
    
    	if (!hwnd)
    		return 0;
    
    	SetTimer(hwnd, 1, 1, NULL);
    	ShowWindow (hwnd, nCmdShow);
    
    	while (GetMessage (&msg, NULL, 0, 0))
    	{
    		TranslateMessage (&msg);
    		DispatchMessage (&msg);
    	}
    }
    
    HDC hdc;
    
    LRESULT CALLBACK MainWindowProc (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
    {
    	static int currentGrid = 0;
    	char s [60];
    	int sum = 0;
    	int i, j;
    	int temp_i, temp_j;
    
    	static unsigned char grid [2] [MAX] [MAX];
    
    	switch (msg)
    	{
    		case WM_CREATE:
    			//MessageBox (hwnd, "hello", "hi", NULL);
    
    			for (i = 0; i < MAX; i++)
    				for (j = 0; j < MAX; j++)
    				{
    					grid [0] [i] [j] = 0;
    					grid [1] [i] [i] = 0;
    				}
    
    			grid [0] [110] [110] = 1;		// Init R-pentomino;
    			grid [0] [110] [111] = 1;
    			grid [0] [111] [109] = 1;
    			grid [0] [111] [110] = 1;
    			grid [0] [112] [110] = 1;
    		break;
    
    		case WM_MOVE:
    		case WM_SIZE:
    			hdc = GetDC (hwnd);
    
    			if (!hdc)
    				break;
    
    			for (i = 0; i < MAX; i++)
    				for (j = 0; j < MAX; j++)
    				{
    					if (grid [currentGrid] [i] [j])
    						SetPixel (hdc, j + 20, i + 20, RGB (255, 0, 0));
    
    					else
    						SetPixel (hdc, j + 20, i + 20, RGB (0, 0, 0));
    				}
    
    			ReleaseDC(hwnd, hdc);
    			hdc = NULL;
    		break;
    
    		case WM_CLOSE:
    		case WM_DESTROY:
    			DestroyWindow (hwnd);
    		break;
    	}
    	
    	hdc = GetDC (hwnd);
    
    	if(hdc)
    	{
    		// Compute:
    		for (i = 0; i < MAX; i++)	
    			for (j = 0; j < MAX; j++)
    			{	
    				// Check top left:
    				temp_i = i - 1;				
    				temp_j = j - 1;
    
    				if (temp_i < 0)
    					temp_i += MAX;
    
    				if (temp_j < 0)
    					temp_j += MAX;
    
    				sum += grid [currentGrid] [temp_i] [temp_j];
    
    				// Check top mid:
    				++temp_j %= MAX;
    				sum += grid [currentGrid] [temp_i] [temp_j];
    
    				// Check top right:
    				++temp_j %= MAX;
    				sum += grid [currentGrid] [temp_i] [temp_j];
    
    				// Check mid right:
    				++temp_i %= MAX;
    				sum += grid [currentGrid] [temp_i] [temp_j];
    
    				// Check mid left:
    				temp_j -= 2;
    
    				if (temp_j < 0)
    					temp_j += MAX;
    				
    				sum += grid [currentGrid] [temp_i] [temp_j];
    
    				// Check bottom left:
    				++temp_i %= MAX;
    				sum += grid [currentGrid] [temp_i] [temp_j];
    
    				// Check bottom mid:
    				++temp_j %= MAX;
    				sum += grid [currentGrid] [temp_i] [temp_j];
    
    				// Check bottom right:
    				++temp_j %= MAX;
    				sum += grid [currentGrid] [temp_i] [temp_j];
    
    				grid [1 - currentGrid] [i] [j] = grid [currentGrid] [i] [j];
    
    				switch (grid [currentGrid] [i] [j])
    				{
    					// If this square alive:
    					case 1:
    						if ((sum < 2) || (sum > 3))
    						{	
    							grid [1 - currentGrid] [i] [j] = 0;
    							SetPixel (hdc, j + 20, i + 20, RGB (0, 0, 0));
    						}
    					break;
    
    					// If this square is dead:
    					case 0:
    						if (sum == 3)
    						{
    							grid [1 - currentGrid] [i] [j] = 1;
    							SetPixel (hdc, j + 20, i + 20, RGB (255, 0, 0));
    						}
    					break;
    				}
    	 
    				sum = 0;
    			}
    			
    		currentGrid ^= 1;
    
    		ReleaseDC(hwnd, hdc);
    		hdc = NULL;
    	}
    
    	return DefWindowProc (hwnd, msg, wParam, lParam);	
    }
    Current Setup: Win 10 with Code::Blocks 17.12 (GNU GCC)

  7. #7
    Chief Code Coloniser!
    Join Date
    Apr 2005
    Posts
    121
    Hello,

    I've made a few changes here and there, please search for my name in the code below.

    Things to note:

    1) You were "painting" every time a window message was being received, instead of doing through some other controlled fashion (such as through timers, as my example shows).
    2) I think the message box just forced some kind of repaint which is what forced the chain of messages that you were getting in order to update the screen. The example given should be a bit more friendly

    Hope that helps!

    Code:
    #include <windows.h>
    
    #define MAX 300
    
    LRESULT CALLBACK MainWindowProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
    
    int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
    {
    	WNDCLASS myWin;
    	MSG msg;
    
    	myWin.style = CS_VREDRAW | CS_HREDRAW;
    	myWin.lpfnWndProc = MainWindowProc;
    	myWin.cbClsExtra = 0;
    	myWin.cbWndExtra = 0;
    	myWin.hInstance = hInstance;
    	myWin.hIcon = LoadIcon (NULL, IDI_APPLICATION);
    	myWin.hCursor = LoadCursor (NULL, IDC_ARROW);
    	myWin.hbrBackground = (HBRUSH) (COLOR_SCROLLBAR + 1);
    	myWin.lpszMenuName = 0;
    	myWin.lpszClassName = "My First App.";
    
    	
    	if (!RegisterClass (&myWin))
    		return 0;
    
    	HWND hwnd;
    
    	hwnd = CreateWindow (	"My First App.",
    							"SamLife, v1.0",
    							WS_OVERLAPPEDWINDOW,
    							20,
    							20,
    							MAX + 40,
    							MAX + 60,
    							NULL,
    							NULL,
    							hInstance,
    							NULL);
    
    	if (!hwnd)
    		return 0;
    
    	SetTimer(hwnd, 1, 1, NULL);
    	ShowWindow (hwnd, nCmdShow);
    
    	while (GetMessage (&msg, NULL, 0, 0))
    	{
    		TranslateMessage (&msg);
    		DispatchMessage (&msg);
    	}
    
        // TheColonial: You need to return a value!
        return 0;
    }
    
    HDC hdc;
    
    LRESULT CALLBACK MainWindowProc (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
    {
        // TheColonial: use a timer, so give it an id.
        static int timerId = 3000;
    	static int currentGrid = 0;
    
        // TheColonial: this variable isn't used.
        // char s [60];
    	int sum = 0;
    	int i, j;
    	int temp_i, temp_j;
    
    	static unsigned char grid [2] [MAX] [MAX];
    
    	switch (msg)
    	{
    		case WM_CREATE:
    			//MessageBox (hwnd, "hello", "hi", NULL);
    
    			for (i = 0; i < MAX; i++)
    				for (j = 0; j < MAX; j++)
    				{
    					grid [0] [i] [j] = 0;
    					grid [1] [i] [i] = 0;
    				}
    
    			grid [0] [110] [110] = 1;		// Init R-pentomino;
    			grid [0] [110] [111] = 1;
    			grid [0] [111] [109] = 1;
    			grid [0] [111] [110] = 1;
    			grid [0] [112] [110] = 1;
    
                // TheColonial: create a timer for the updates. fire every half second
                SetTimer(hwnd, timerId, 500, NULL);
    		break;
    
    		case WM_MOVE:
    		case WM_SIZE:
    			hdc = GetDC (hwnd);
    
    			if (!hdc)
    				break;
    
    			for (i = 0; i < MAX; i++)
    				for (j = 0; j < MAX; j++)
    				{
    					if (grid [currentGrid] [i] [j])
    						SetPixel (hdc, j + 20, i + 20, RGB (255, 0, 0));
    
    					else
    						SetPixel (hdc, j + 20, i + 20, RGB (0, 0, 0));
    				}
    
    			ReleaseDC(hwnd, hdc);
    			hdc = NULL;
    		break;
    
            // TheColonial: Check out the following changes
    		case WM_CLOSE:
                // Destroy on WM_CLOSE, NOT on WM_DESTROY
    			DestroyWindow (hwnd);
                break;
    		case WM_DESTROY:
                // TheColonial: finish the timer
                KillTimer(hwnd, timerId);
                // quit when destroyed
                PostQuitMessage(0);
    		    break;
            case WM_TIMER:
                {
                    // handle the painting through the timer.
    	            hdc = GetDC (hwnd);
    
    	            if(hdc)
    	            {
    		            // Compute:
    		            for (i = 0; i < MAX; i++)	
    			            for (j = 0; j < MAX; j++)
    			            {	
    				            // Check top left:
    				            temp_i = i - 1;				
    				            temp_j = j - 1;
    
    				            if (temp_i < 0)
    					            temp_i += MAX;
    
    				            if (temp_j < 0)
    					            temp_j += MAX;
    
    				            sum += grid [currentGrid] [temp_i] [temp_j];
    
    				            // Check top mid:
    				            ++temp_j %= MAX;
    				            sum += grid [currentGrid] [temp_i] [temp_j];
    
    				            // Check top right:
    				            ++temp_j %= MAX;
    				            sum += grid [currentGrid] [temp_i] [temp_j];
    
    				            // Check mid right:
    				            ++temp_i %= MAX;
    				            sum += grid [currentGrid] [temp_i] [temp_j];
    
    				            // Check mid left:
    				            temp_j -= 2;
    
    				            if (temp_j < 0)
    					            temp_j += MAX;
    				            
    				            sum += grid [currentGrid] [temp_i] [temp_j];
    
    				            // Check bottom left:
    				            ++temp_i %= MAX;
    				            sum += grid [currentGrid] [temp_i] [temp_j];
    
    				            // Check bottom mid:
    				            ++temp_j %= MAX;
    				            sum += grid [currentGrid] [temp_i] [temp_j];
    
    				            // Check bottom right:
    				            ++temp_j %= MAX;
    				            sum += grid [currentGrid] [temp_i] [temp_j];
    
    				            grid [1 - currentGrid] [i] [j] = grid [currentGrid] [i] [j];
    
    				            switch (grid [currentGrid] [i] [j])
    				            {
    					            // If this square alive:
    					            case 1:
    						            if ((sum < 2) || (sum > 3))
    						            {	
    							            grid [1 - currentGrid] [i] [j] = 0;
    							            SetPixel (hdc, j + 20, i + 20, RGB (0, 0, 0));
    						            }
    					            break;
    
    					            // If this square is dead:
    					            case 0:
    						            if (sum == 3)
    						            {
    							            grid [1 - currentGrid] [i] [j] = 1;
    							            SetPixel (hdc, j + 20, i + 20, RGB (255, 0, 0));
    						            }
    					            break;
    				            }
    	             
    				            sum = 0;
    			            }
    			            
    		            currentGrid ^= 1;
    
    		            ReleaseDC(hwnd, hdc);
    		            hdc = NULL;
                    }
                    break;
                }
            }
    
    	return DefWindowProc (hwnd, msg, wParam, lParam);	
    }

  8. #8
    Registered User samGwilliam's Avatar
    Join Date
    Feb 2002
    Location
    Newport
    Posts
    382
    That's great! Thanks! I apologise for my abrasiveness. I have a very bad temper with computers (I broke a cup while trying to sort this problem out ).
    Last edited by samGwilliam; 04-12-2005 at 07:10 AM.
    Current Setup: Win 10 with Code::Blocks 17.12 (GNU GCC)

  9. #9
    Chief Code Coloniser!
    Join Date
    Apr 2005
    Posts
    121
    No need for apologise.. we've all been there, and there's no doubt we'll all go there again

  10. #10
    Yes, my avatar is stolen anonytmouse's Avatar
    Join Date
    Dec 2002
    Posts
    2,544
    You should paint when you receive a WM_PAINT message. A WM_PAINT will be posted when Windows needs the window repainted. For example, when it is exposed from behind another window. You can paint while handling another message but the typical procedure is to call InvalidateRect (and optionally UpdateWindow) to trigger a WM_PAINT and keep the painting code inside the WM_PAINT handler.

    Here is what a WM_PAINT handler looks like:
    Code:
    case WM_PAINT:
    {
        PAINTSTRUCT ps;
        HDC hdc = BeginPaint(hwnd, &ps);
    
        /* Do your drawing here using hdc. */
    
        EndPaint(hwnd, &ps);
        return 0;
    }
    >> Commenting out a MessageBox statement has altered the entire logic of the program or something. <<

    Yes calling MessageBox will interact and alter how a window works.
    - MessageBox has its own inbuilt message pump.
    - When the message box is shown, your window will lose focus,
    - When the message box is dismissed, your window will regain focus and if your window was behind the message box it will be posted a WM_PAINT message to repaint the affected area.
    - Because MessageBox runs its own message loop, it is re-entrant. For example, if you call MessageBox in your WM_PAINT handler, you may get dozens of message boxes on the screen.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. how to make a windows application
    By crvenkapa in forum C++ Programming
    Replies: 3
    Last Post: 03-26-2007, 09:59 AM
  2. Script errors - bool unrecognized and struct issues
    By ulillillia in forum Windows Programming
    Replies: 10
    Last Post: 12-18-2006, 04:44 AM
  3. Question..
    By pode in forum Windows Programming
    Replies: 12
    Last Post: 12-19-2004, 07:05 PM
  4. IE 6 status bar
    By DavidP in forum Tech Board
    Replies: 15
    Last Post: 10-23-2002, 05:31 PM
  5. Manipulating the Windows Clipboard
    By Johno in forum Windows Programming
    Replies: 2
    Last Post: 10-01-2002, 09:37 AM