Sign in to follow this  
spiggo89

Windows Dialog box not redrawing

Recommended Posts

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]

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this