C++ 在C+中的3个按钮上绘制位图+;Win32应用程序

C++ 在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

我有一个win32应用程序,我把它放在主窗口(用CreateWindowEx创建)3个按钮中。我想把它们分开两行,所以我想在每个按钮之间放置一个位图,但是当我试图在WM_PAINT中绘制图像时,它会将其放置在最后一个按钮之后,如果X和Y坐标为0,0。为什么?我是否应该放置一个静态控件并使用STM_SETIMAGE设置图像背景

编辑1

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;
}

我添加了用于绘制位图图像的代码。您可以发布一个屏幕抓图,显示您渲染的内容和您希望渲染的内容吗?添加了,顶部图像显示窗口当前渲染的方式,底部图像快照窗口应如何渲染。黑线是我要在每个按钮之间添加的图像(它们是图像的红色部分),但仍然没有足够的上下文来了解您正在做什么。屏幕截图没有显示任何按钮,也没有创建按钮的代码