Win32 API背景图片问题 [英] Win32 API background image problems

查看:167
本文介绍了Win32 API背景图片问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

大家好!



我想首先感谢所有花时间查看此主题并尝试提供帮助的人。



我在一个项目上工作,其中.bmp文件必须是主窗口的背景图片。



我在MS工作Visual Studio Express Edition 2008,在C ++中,在Windows XP上使用WIN32 API。



我在CodeProject上找到了将.bmp文件作为背景图像的解决方案。



修改我的代码后,我的应用程序启动后一切正常。图片应该是它的位置。



当我最大化主窗口时出现问题。

图片重复,经过几次最小化/最大化后,我的背景变成了全白。



我将提交我的代码,希望它有助于找到解决方案。



位图尺寸是256 x 256,它是通过我在网上找到的免费转换器从.png文件创建的(.png文件非常大)。



我甚至有在Paint中捕获了一些问题的快照,但我不知道如何让那些查看这个问题的人可以使用它们(我很乐意通过电子邮件发送给他们)。



如果还有什么我可以做的,就说出来,我会做的。



重要更新#1 (更新于2013年5月5日):



添加以下代码后,图片不再重复,但在极少数/最大化后,我的背景变为白色:< br $>


Hello everyone!

I would like to start by saying thanks to everyone who takes some time to view this thread and try to help.

I work on a project where .bmp file must be a background image of a main window.

I work in MS Visual Studio Express Edition 2008, in C++, using WIN32 API, on Windows XP.

I have found solution for putting .bmp file as background image here, on CodeProject.

After modifying my code everything worked fine after my application started.The picture was where it supposed to be.

The problem comes when I maximize the main window.
The picture gets duplicated, and after few more minimizes/maximizes, my background becomes entirely white.

I will submit my code in hope that it will help in finding a solution.

Bitmaps dimensions are 256 x 256, and it was created from a .png file via free converter I have found online (the .png file was quite large).

I have even captured some snapshots of the problem in Paint, but I don''t know how to make them available to those who view this question ( I will gladly e-mail them).

If there is anything else I can do, just say it, and I will do it.

IMPORTANT UPDATE #1 ( updated on May,5th 2013):

After adding the following code, picture doesn''t duplicate anymore, but after few minimizes/maximizes my background becomes white :

case WM_SIZE:
        InvalidateRect(hwnd,NULL,FALSE);
        break;





重要更新#2 (2013年5月5日更新):



我已经在窗口类注册的部分更改了我的代码



IMPORTANT UPDATE #2 ( updated on May,5th 2013):

I have changed my code in the part where the window class is registered from

wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);



to


to

wc.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);





几次最小化/最大化后,图片完全消失,背景变黑(正如我已经改变了它,在窗口类注册中)。

我怀疑问题是某种泄漏,但我无法弄明白。



重要更新#3 (2013年5月5日更新):



我已经解决了问题,并已提交我的解决方案。

请评论它,我会欢迎它。

我也会接受其他解决方案。

谢谢。



现在,这个e代码:





After few minimizes/maximizes the picture completely dissapears and background becomes black ( just as I have changed it, in window class registration).
I suspect that the problem is some sort of a leak,but I just can''t figure it out.

IMPORTANT UPDATE #3 ( updated on May, 5th 2013):

I have solved the problem, and have submitted my solution.
Please comment on it, I will welcome it.
I will also accept other solutions, as well.
Thank you.

Now, the code:

#include "resource.h"
#include <windows.h>

// THIS DIALOG IS IRRELEVANT FOR MY QUESTION

BOOL CALLBACK FilterDialog( HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam )
{
	switch( Message)
	{
	case WM_INITDIALOG:
		return TRUE;
		break;

	case WM_COMMAND:
		switch( LOWORD(wParam) )
		{
		case IDOK:
			EndDialog(hwnd, IDOK);
			break;
		case IDCANCEL:
			EndDialog(hwnd, IDCANCEL);
			break;
		}

		break;

	default:
		return FALSE;
	}

	return TRUE;
}

/*************************** main window procedure *******************************/

LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
	HBITMAP hBitmap = LoadBitmap( GetModuleHandle(NULL), MAKEINTRESOURCE(IDB_BITMAP1) );
	
	// Dimensions of a bitmap that will be painted on client area

	BITMAP bp;
	GetObject( hBitmap, sizeof(bp), &bp);

	switch(msg)
	{
	case WM_PAINT:

		HDC hdcInst,hdcBitmap;
		PAINTSTRUCT ps;

		hdcInst = BeginPaint(hwnd,&ps);
		
		// Create a memory device compatible with the above DC variable

		hdcBitmap = CreateCompatibleDC(hdcInst);

		// Select the new bitmap

		SelectObject(hdcBitmap, hBitmap);

		// Get client coordinates for the StretchBlt() function

		RECT r;
		GetClientRect(hwnd,&r);

		// troublesome part, in my oppinion
		
		StretchBlt( hdcInst, 0, 0, r.right - r.left, r.bottom - r.top, hdcBitmap, 0, 0, bp.bmWidth,bp.bmHeight, MERGECOPY); 

		// Cleanup

		DeleteDC(hdcBitmap);
		EndPaint(hwnd, &ps);

		break;

        // WM_COMMAND handles creation of a dialog, and is irrelevant for my question

	case WM_COMMAND:
		switch( LOWORD(wParam) )
		{
		case IDM_PRETRAGA1:
			DialogBox( GetModuleHandle(NULL), MAKEINTRESOURCE(IDD_DIALOG1),hwnd,FilterDialog);
			break;
		default:
			break;
		}

		break;

	case WM_CLOSE:
                // delete bitmap handle
		DeleteObject(hBitmap);

		DestroyWindow(hwnd);
		break;

	case WM_DESTROY:
                // delete bitmap handle
		DeleteObject(hBitmap);

		PostQuitMessage(0);
		break;

	default:
		return DefWindowProc(hwnd, msg, wParam, lParam);
	}
	return 0;
}

/******************************* WinMain ************************************/

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,LPSTR lpCmdLine, int nCmdShow)
{
	WNDCLASSEX wc;
	HWND hwnd;
	MSG Msg;

	wc.cbSize = sizeof(WNDCLASSEX);
	wc.style = 0;
	wc.lpfnWndProc = WndProc;
	wc.cbClsExtra = 0;
	wc.cbWndExtra = 0;
	wc.hInstance = hInstance;
	wc.hIcon = LoadIcon(hInstance,MAKEINTRESOURCE(IDI_ICON1)); // icon from resource
	wc.hCursor = LoadCursor(NULL, IDC_ARROW);
	wc.hbrBackground =(HBRUSH)(COLOR_WINDOW+1); 
	wc.lpszMenuName = MAKEINTRESOURCE(IDR_MENU1); // menu from resource
	wc.lpszClassName = "Main_Window";
	wc.hIconSm = (HICON)LoadImage(hInstance,MAKEINTRESOURCE(IDI_ICON1),IMAGE_ICON,16,16,0); // icon from resource

	if(!RegisterClassEx(&wc))
	{
		MessageBox(NULL, "Window Registration Failed!", "Error!", MB_ICONEXCLAMATION | MB_OK);
		return 0;
	}

	/************************ main window *************************/

	hwnd = CreateWindowEx(WS_EX_CLIENTEDGE, "Main_Window", "Rudarsko Geoloski Fakultet",
		WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 800, 500, NULL, NULL, hInstance, NULL);

	if(hwnd == NULL)
	{
		MessageBox(NULL, "Window Creation Failed!", "Error!", MB_ICONEXCLAMATION | MB_OK);
		return 0;
	}

	ShowWindow(hwnd, nCmdShow);
	UpdateWindow(hwnd);

	while(GetMessage(&Msg, NULL, 0, 0) > 0)
	{
		TranslateMessage(&Msg);
		DispatchMessage(&Msg);
	}

	return Msg.wParam;
}

推荐答案

我破解了它!



只需进行一些修改,一切正常。



重要信息:

此解决方案得到了改进,这要归功于会员CPallini的评论。



以下是最终调整:



I have cracked it!

Just a few modifications, and it all works.

IMPORTANT INFORMATION:
This solution was improved thanks to remarks from member CPallini.

Here are the final adjustments:

// hBitmap variable is declared as static and is outside of switch(...) statement

static HBITMAP hBitmap = LoadBitmap( GetModuleHandle(NULL), 
                          MAKEINTRESOURCE(IDB_BITMAP1) );

// solved issue with duplicated picture with InvalidateRect(...);
case WM_SIZE:
     InvalidateRect(hwnd,NULL,FALSE);
     break;

// added curly braces, HBITMAP variable is declared static,cleanup is reorganized

case WM_PAINT:
{
     HDC hdcInst,hdcBitmap;
     PAINTSTRUCT ps;
     BITMAP bp;
     RECT r;
     
     hdcInst = BeginPaint(hwnd,&ps);
		
     // Create a memory device compatible with the above DC variable

     hdcBitmap = CreateCompatibleDC( hdcInst);
 
     // Select the new bitmap

     SelectObject(hdcBitmap, hBitmap);
			
     GetObject( hBitmap, sizeof(bp), &bp);
		
     // Get client coordinates for the StretchBlt() function

     GetClientRect(hwnd,&r);
 
     // stretch bitmap across client area
		
     StretchBlt( hdcInst, 0, 0,r.right - r.left, r.bottom - r.top, hdcBitmap, 0, 
         0, bp.bmWidth,bp.bmHeight, SRCCOPY); 
 
     // Cleanup

     DeleteDC(hdcBitmap);
     EndPaint(hwnd, &ps);
}
     break;

// this part below removes flickering !

case WM_ERASEBKGND:
     return (LRESULT)1;

// cleanup for bitmap

case WM_CLOSE:

     DeleteObject(hBitmap);
     DestroyWindow(hwnd);
     break;

case WM_DESTROY:

     DeleteObject(hBitmap);
     PostQuitMessage(0);
     break;


这篇关于Win32 API背景图片问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆