C++ 在C+中的3个按钮上绘制位图+;Win32应用程序
我有一个win32应用程序,我把它放在主窗口(用CreateWindowEx创建)3个按钮中。我想把它们分开两行,所以我想在每个按钮之间放置一个位图,但是当我试图在WM_PAINT中绘制图像时,它会将其放置在最后一个按钮之后,如果X和Y坐标为0,0。为什么?我是否应该放置一个静态控件并使用STM_SETIMAGE设置图像背景 编辑1C++ 在C+中的3个按钮上绘制位图+;Win32应用程序,c++,winapi,C++,Winapi,我有一个win32应用程序,我把它放在主窗口(用CreateWindowEx创建)3个按钮中。我想把它们分开两行,所以我想在每个按钮之间放置一个位图,但是当我试图在WM_PAINT中绘制图像时,它会将其放置在最后一个按钮之后,如果X和Y坐标为0,0。为什么?我是否应该放置一个静态控件并使用STM_SETIMAGE设置图像背景 编辑1 hdc = BeginPaint(hWnd, &ps); HDC hdcMem; hdcMem = CreateCompatibleDC(hdc); BIT
hdc = BeginPaint(hWnd, &ps);
HDC hdcMem;
hdcMem = CreateCompatibleDC(hdc);
BITMAP bm;
HBITMAP oldbitmap;
GetObject(test, sizeof(bm), &bm);
oldbitmap = (HBITMAP)SelectObject(hdcMem, test);
BitBlt(hdc, 10, 10, bm.bmWidth, bm.bmHeight, hdcMem, 0, 0, SRCCOPY);
SelectObject(hdcMem, oldbitmap);
DeleteObject(oldbitmap);
DeleteDC(hdcMem);
EndPaint(hWnd, &ps);
编辑2
你的最后一条评论已经发出了危险信号 无需创建窗口即可绘制黑线。对窗口系统的工作原理似乎存在一些误解 所以,为了建立这个:
|--------------------------------|
|MainWindow B |
| l |
| |--------| a |--------| |
| |Button1 | c |Button2 | |
| | | k | | |
| | | | | |
| | | B | | |
| | | a | | |
| |--------| r |--------| |
|--------------------------------|
首先调用CreateWindow创建主窗口,然后输入消息循环(GetMessage、Translate、Dispatch等)。然后,在主窗口的WM_创建处理程序中,使用消息处理程序的窗口参数作为按钮的父窗口,创建Button1和Button2
要绘制黑条,您需要在主窗口的消息处理程序中为WM_橡皮擦BKGND消息添加一个处理程序,并在该处理程序中清除客户端区域(通过调用DefWindowProc),然后绘制黑条
按钮的绘制应由按钮窗口的WM_橡皮擦BKGND/WM_绘制处理程序处理,而不是由主窗口处理
编辑:这里有一个简单的程序,显示两个按钮和一个黑条:
#define WIN32_MEAN_AND_LEAN
#include <windows.h>
// a helper function to create two buttons
void CreateButtons (HWND parent)
{
// create two button
// Here, I've used the standard button class. If you want to have red buttons,
// either create a new class for the buttons and implement all the functionality
// yourself, or sub class the standard button and override the drawing functions.
CreateWindowEx (0,
TEXT ("BUTTON"),
TEXT ("Button1"),
WS_CHILD | WS_VISIBLE,
10,
10,
100,
50,
parent,
0,
reinterpret_cast <HINSTANCE> (GetWindowLongPtr (parent, GWL_HINSTANCE)),
0);
CreateWindowEx (0,
TEXT ("BUTTON"),
TEXT ("Button2"),
WS_CHILD | WS_VISIBLE,
140,
10,
100,
50,
parent,
0,
reinterpret_cast <HINSTANCE> (GetWindowLongPtr (parent, GWL_HINSTANCE)),
0);
}
LRESULT CALLBACK MainWindowProc (HWND window, UINT message, WPARAM w_param, LPARAM l_param)
{
LRESULT
result;
bool
use_default_proc = true;
switch (message)
{
case WM_CREATE:
// when the window is created, create the two buttons!
CreateButtons (window);
break;
case WM_DESTROY:
// when the window is finished with, call PostQuitMessage to exit the message loop
PostQuitMessage (0);
use_default_proc = false;
result = 0;
break;
case WM_ERASEBKGND:
// here we draw the black line between the two buttons using a solid colour filled rectangle.
// this can just as easily be done in the WM_PAINT handler
{
// DefWindowProc will clear the window using the WNDCLASSEX.hbrBackground member
result = DefWindowProc (window, message, w_param, l_param);
use_default_proc = false;
// get the DC to draw with
HDC
dc = reinterpret_cast <HDC> (w_param);
// draw the black bar
RECT
rect = {120, 0, 130, 70};
FillRect (dc, &rect, reinterpret_cast <HBRUSH> (GetStockObject (BLACK_BRUSH)));
}
break;
}
if (use_default_proc)
{
result = DefWindowProc (window, message, w_param, l_param);
}
return result;
}
int __stdcall WinMain (HINSTANCE instance, HINSTANCE previous_instance, LPSTR command_line, int show_command)
{
// create a window class for the main window
WNDCLASSEX
window_class =
{
sizeof window_class,
CS_HREDRAW | CS_VREDRAW,
MainWindowProc,
0,
0,
instance,
0,
LoadCursor (0, IDC_ARROW),
reinterpret_cast <HBRUSH> (COLOR_WINDOW + 1),
0,
TEXT ("MainWindowClass"),
0
};
// register the window class
RegisterClassEx (&window_class);
// create the main window
HWND
window = CreateWindowEx (WS_EX_APPWINDOW,
TEXT ("MainWindowClass"),
TEXT ("Example Window"),
WS_OVERLAPPEDWINDOW | WS_VISIBLE,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
0,
0,
instance,
0);
bool
quit = false;
while (!quit)
{
MSG
message;
int
error_code;
switch (GetMessage (&message, 0, 0, 0))
{
case 0: // WM_QUIT processed
quit = true;
break;
case -1: // an error
error_code = GetLastError ();
quit = true;
break;
default: // pass the message on to the window...
TranslateMessage (&message);
DispatchMessage (&message);
break;
}
}
return 0;
}
#定义WIN32(意味着)和(精益)
#包括
//用于创建两个按钮的辅助函数
无效创建按钮(HWND父级)
{
//创建两个按钮
//在这里,我使用了标准按钮类。如果你想要红色按钮,
//为按钮创建一个新类并实现所有功能
//您自己,或对标准按钮进行子类化,并替代图形功能。
CreateWindowEx(0,
文本(“按钮”),
文本(“按钮1”),
WS|u CHILD | WS|u可见,
10,
10,
100,
50,
父母亲
0,
重新解释强制转换(GetWindowLongPtr(父级,GWL_HINSTANCE)),
0);
CreateWindowEx(0,
文本(“按钮”),
文本(“按钮2”),
WS|u CHILD | WS|u可见,
140,
10,
100,
50,
父母亲
0,
重新解释强制转换(GetWindowLongPtr(父级,GWL_HINSTANCE)),
0);
}
LRESULT回调MainWindowProc(HWND窗口、UINT消息、WPARAM w_参数、LPARAM l_参数)
{
勒索
结果;
布尔
使用\u default\u proc=true;
开关(信息)
{
案例WM_创建:
//创建窗口时,创建两个按钮!
创建按钮(窗口);
打破
案例WM_销毁:
//当窗口结束时,调用PostQuitMessage退出消息循环
PostQuitMessage(0);
使用\u default\u proc=false;
结果=0;
打破
案例WM_擦除BKGND:
//在这里,我们使用纯色填充矩形在两个按钮之间绘制黑线。
//这可以在WM_PAINT处理程序中轻松完成
{
//DefWindowProc将使用WNDCLASSEX.hbrBackground成员清除窗口
结果=DefWindowProc(窗口、消息、w_参数、l_参数);
使用\u default\u proc=false;
//让DC与您一起绘图
HDC
dc=重新解释铸件(w_参数);
//画黑条
直肠
rect={120,0,130,70};
FillRect(dc,&rect,reinterpret_cast(GetStockObject(黑色画笔));
}
打破
}
如果(使用默认程序)
{
结果=DefWindowProc(窗口、消息、w_参数、l_参数);
}
返回结果;
}
int\uu stdcall WinMain(HINSTANCE实例、HINSTANCE上一个实例、LPSTR命令行、int show命令)
{
//为主窗口创建窗口类
WNDCLASSEX
窗口类=
{
窗口类的大小,
C|u HREDRAW | C|u VREDRAW,
MainWindowProc,
0,
0,
比如,,
0,
加载光标(0,IDC_箭头),
重新解释投影(颜色窗口+1),
0,
文本(“MainWindowClass”),
0
};
//注册窗口类
注册表类(窗口类);
//创建主窗口
HWND
window=CreateWindowEx(WS_EX_APPWINDOW,
文本(“MainWindowClass”),
文本(“示例窗口”),
WS|U重叠窗口| WS|U可见,
CW_使用默认值,
CW_使用默认值,
CW_使用默认值,
CW_使用默认值,
0,
0,
比如,,
0);
布尔
退出=错误;
而(!退出)
{
味精
消息
int
错误代码;
开关(GetMessage(&message,0,0,0))
{
案例0://WM\u退出已处理
退出=真;
打破
案例1://一个错误
错误代码=GetLastError();
退出=真;
打破
默认值://将消息传递到窗口。。。
翻译消息(和消息);
DispatchMessage(&message);
打破
}
}
返回0;
}
我添加了用于绘制位图图像的代码。您可以发布一个屏幕抓图,显示您渲染的内容和您希望渲染的内容吗?添加了,顶部图像显示窗口当前渲染的方式,底部图像快照窗口应如何渲染。黑线是我要在每个按钮之间添加的图像(它们是图像的红色部分),但仍然没有足够的上下文来了解您正在做什么。屏幕截图没有显示任何按钮,也没有创建按钮的代码