Windows Dialog box not redrawing

Started by
5 comments, last by streamer 15 years, 11 months ago
I am currently working on a map editor for my game, and I am using the standard win32 api to do it. I have created a dialog in my resource file, and instantiated it with DialogBox(), but if i open an open file dialog for example, the part of my dialog that the file dialog obscured is NOT redrawn when it regains focus, the only way to make it redraw is to move the window by clicking the title bar. Any suggestions would be very helpful. My code is here:
#include <windows.h>
#include "resource.h"
#include <fstream>
#include "Graphics\Renderer.h"
#include <map>

std::map<int, Animation *> animations;
Renderer * renderer;
int texture;

LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
BOOL CALLBACK DlgProc(HWND, UINT, WPARAM, LPARAM);
char * openFileDialog(char * filename);
bool loadAnimationFile(const char * filename, HWND listBox);
bool loadFramesForAnimation(int animationID, HWND listBox);

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd) {
	MSG msg;
    texture = 1;
	/*HWND hwnd;
	WNDCLASS wndClass;

	wndClass.style = CS_HREDRAW | CS_VREDRAW;
	wndClass.lpfnWndProc = WndProc;
	wndClass.cbClsExtra = 0;
	wndClass.cbWndExtra = 0;
	wndClass.hInstance = hInstance;
	wndClass.hIcon = 0;
	wndClass.hCursor = LoadCursor(0, IDC_ARROW);
	wndClass.hbrBackground = (HBRUSH) GetStockObject(WHITE_BRUSH);
	wndClass.lpszMenuName = MAKEINTRESOURCE(IDR_MENU1);
	wndClass.lpszClassName = TEXT("Program");

	RegisterClass(&wndClass);

	hwnd = CreateWindow(TEXT("Program"),
						TEXT("Demo"),
						WS_OVERLAPPEDWINDOW,
						CW_USEDEFAULT, CW_USEDEFAULT,
						CW_USEDEFAULT, CW_USEDEFAULT,
						0, 0, hInstance, 0);

	ShowWindow(hwnd, nShowCmd);
	UpdateWindow(hwnd);*/

	DialogBox(hInstance, MAKEINTRESOURCE(IDD_MYDIALOG), 0, DlgProc);

	while(GetMessage(&msg, 0, 0, 0)) {
		TranslateMessage(&msg);
		DispatchMessage(&msg);
	}
	return msg.wParam;
}

//LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) {
//	static HINSTANCE hInstance;
//	int j = 0;
//
//	switch(message) {
//		case WM_CREATE:
//			hInstance = ((LPCREATESTRUCT) lParam)->hInstance;
//			//DialogBox(hInstance, MAKEINTRESOURCE(IDD_MYDIALOG), hwnd, AboutDlgProc);
//			return 0;
//
//		case WM_COMMAND:
//			switch(LOWORD(wParam)) {
//				case ID_FILE_ABOUT:
//					MessageBox(hwnd, TEXT("Hello"), TEXT("Hello"), 0);
//					
//					return 0;
//
//				case ID_FILE_EXIT:
//					PostQuitMessage(0);
//					return 0;
//			};
//			break;
//
//		case WM_DESTROY:
//			PostQuitMessage(0);
//			return 0;
//	}
//	return DefWindowProc(hwnd, message, wParam, lParam);
//}

BOOL CALLBACK DlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) {
	HWND listbox = 0;
    Object obj;

	switch(message) {
        case WM_PAINT:
            obj.setTexture(texture);
            //renderer->addObject(&obj, 0, 0);
            //renderer->Render();
            return true;
	    case WM_INITDIALOG:
            //renderer = new Renderer(GetDlgItem(hDlg, IDC_DRAWFRAME), 0);
			return true;

		case WM_COMMAND:
			switch(LOWORD(wParam)) {
				case IDOPENANIMATIONFILE:
					loadAnimationFile(openFileDialog(0), GetDlgItem(hDlg, IDC_ANIMATIONLIST));
					break;

				case IDEXIT:
					EndDialog(hDlg, 0);
					PostQuitMessage(0);
					return true;

                case IDC_ANIMATIONLIST:
                    switch(HIWORD(wParam)) {
                        case LBN_SELCHANGE:
                            loadFramesForAnimation(1, GetDlgItem(hDlg, IDC_FRAMELIST));
                            break;
                    }
                    break;

                case IDC_FRAMELIST:
                    switch(HIWORD(wParam)) {
                        case LBN_SELCHANGE:
                            texture = SendMessage(GetDlgItem(hDlg, IDC_FRAMELIST), LB_GETCURSEL, 0, 0);
                            break;
                    }
                    break;
			}
			break;

        case WM_CLOSE:
			PostQuitMessage(0);
			return 0;
	}
	return false;
}

bool loadFramesForAnimation(int animationID, HWND listBox) {
    SendMessage(listBox, LB_RESETCONTENT, 0, 0);
    Animation * anim = animations[animationID];

    for(int i = 0; i < anim->numFrames; i++) {
        char name[10];
        sprintf(name, "Frame%d", i);
        SendMessage(listBox, LB_ADDSTRING, 0, (LPARAM)name);
    }
    return true;
}

bool loadAnimationFile(const char * filename, HWND listBox) {
    SendMessage(listBox, LB_RESETCONTENT, 0, 0);
    std::ifstream afile;
    afile.open("anim.dat", std::ifstream::in, std::ifstream::binary);
    if(!afile.good()) {
        MessageBox(0, "ERROR: Could not open file", (LPCSTR)filename, 0);
        return false;
    }

    animFileHeader filehead;
    afile.read((char *)&filehead, sizeof(animFileHeader));

    if(memcmp(filehead.ident, "SS13", 4)) {
        MessageBox(0, "ERROR: Corrupted animation file.", "Fatal Error", 0);
        return false;
    }

    animHeader ahead;

    Animation *anim = new Animation;

    for(int i = 0; i < filehead.numAnimations; i++) {
        afile.read((char *)&ahead, sizeof(animHeader));
        int len = 0;
        afile.read((char *)&len, 1);
        char * animName = new char[len];
        afile.read(animName, len);
        anim->name = animName;
        anim->animationID = ahead.animID;
        anim->numFrames = ahead.numFrames;
        anim->frames = new animFrame[anim->numFrames];

        for(int j = 0; j < ahead.numFrames; j++) {
            afile.read((char *)&anim->frames[j], sizeof(animFrame));            
        }
        animations[anim->animationID] = anim;
        SendMessage(listBox, LB_ADDSTRING, 0, (LPARAM)anim->name);
    }
    
    return true;
}

char * openFileDialog(char * filename) {
	if(!filename) {
		filename = new char[256];
	}
	memset(filename, 0x00, 256);

	OPENFILENAME opf;
	opf.hwndOwner = 0;
	opf.hInstance = GetModuleHandle(0);
	opf.lpstrFilter = TEXT("Dat Files (*.dat)\0*.dat\0\0");
	opf.lpstrCustomFilter = 0;
	opf.nMaxCustFilter = 0L;
	opf.nFilterIndex = 1L;
	opf.lpstrFile = (LPSTR)filename;
	opf.nMaxFile = 255;
	opf.lpstrFileTitle = 0;
	opf.nMaxFileTitle=50;
	opf.lpstrInitialDir = 0;
	opf.lpstrTitle = 0;
	opf.nFileOffset = 0;
	opf.nFileExtension = 2;
	opf.lpstrDefExt = TEXT("*.dat");
	opf.lpfnHook = NULL;
	opf.lCustData = 0;
	opf.Flags = OFN_PATHMUSTEXIST;
	opf.lStructSize = sizeof(OPENFILENAMEW);
	GetOpenFileName(&opf);

	return filename;
}
[Edited by - spiggo89 on May 8, 2008 7:28:19 PM]
Advertisement
Hi
Try to put on the end of loading routine:
UpdateWindow( HWND hWnd );

It will send WM_PAINT message to window and it will be repainted.

Hope this helps
I presume you mean your main window? You should be handling WM_PAINT messages to prevent things like this. Whenever you get a WM_PAINT message, Windows is telling you that you need to redraw (at least a part of) your window.

In your current code, you're not handling WM_PAINT at all, so your window isn't redrawing, so you're seeing whatever was there before.
Quote:Original post by Evil Steve
I presume you mean your main window? You should be handling WM_PAINT messages to prevent things like this. Whenever you get a WM_PAINT message, Windows is telling you that you need to redraw (at least a part of) your window.

In your current code, you're not handling WM_PAINT at all, so your window isn't redrawing, so you're seeing whatever was there before.


He is handling something. But it is commented. [smile] So you are right. He is not handling it.

Anyway spiggo you should use code formatting. Look in FAQ in upper right corner.
Quote:Original post by streamer
He is handling something. But it is commented. [smile] So you are right. He is not handling it.
Oh, I see - I got confused by the creation of the window and then dialog box [smile]

You could use a modeless dialog box instead, that might be more suitable here. However, I'm not entirely sure it's valid to handle WM_PAINT for a dialog box - surely the OS is supposed to handle that, and you're just supposed to repaint controls? In any case, you're not even calling BeginPaint() or EndPaint(), which you're supposed to do in response to a WM_PAINT message.

I'd recommend creating a custom control (Which is basically just registering a window class) for your render output, and then removing the WM_PAINT handling in the parent dialog box.
I have fixed the issue by using CreateDialog() instead of DialogBox(), also I did add Begin/EndPaint() to the WM_PAINT routine, and it DID update, but only one every second, which is much too slow.
WM_PAINT message is not called every frame. It is called when it needs repaint (ie when you move window)
You can make one timer that will send WM_PAINT message every 100 ms.

This topic is closed to new replies.

Advertisement