上次那个问题http://topic.csdn.net/u/20090324/20/a9958c0c-0018-45c5-9f58-54a3214ad600.html
没有源代码说不清楚
现在贴出来了
地址:http://topic.csdn.net/u/20090326/18/c8c915ca-6dd9-461f-bffe-423bcbf01b87.html?seed=317565127我试了下面的代码
右击能显示出图片
但是我如果把那段注释的代码加上去
也就是有WM_PAINT的消息
就不能正常显示
谁能解释一下原因
#include<windows.h>LRESULT CALLBACK WndProc(HWND,UINT,WPARAM,LPARAM);
LRESULT CALLBACK ButtonProc(HWND,UINT,WPARAM,LPARAM);HWND hwndBN;
WNDPROC oldButton;
HBITMAP hBitmap;int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nCmdShow)
{
static TCHAR AppName[]=TEXT("Mine");
HWND hwnd;
MSG msg;
WNDCLASS wndclass; wndclass.style         = CS_HREDRAW | CS_VREDRAW ;
wndclass.lpfnWndProc   = WndProc ;
wndclass.cbClsExtra    = 0 ;
wndclass.cbWndExtra    = 0 ;
wndclass.hInstance     = hInstance ;
wndclass.hIcon         = LoadIcon (NULL, IDI_APPLICATION) ;
wndclass.hCursor       = LoadCursor (NULL, IDC_ARROW) ;
wndclass.hbrBackground = (HBRUSH) GetStockObject(WHITE_BRUSH) ;
wndclass.lpszMenuName  = AppName ;
wndclass.lpszClassName = AppName ; if (!RegisterClass (&wndclass))
{
MessageBox (NULL, TEXT ("This program requires Windows NT!"), 
  AppName, MB_ICONERROR) ;
return 0 ;
}
hwnd=CreateWindow(AppName,AppName,WS_OVERLAPPEDWINDOW & ~WS_THICKFRAME & ~WS_MAXIMIZEBOX ,
CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,NULL,NULL,hInstance,NULL);
ShowWindow(hwnd,nCmdShow);
UpdateWindow(hwnd); while (GetMessage(&msg,NULL,0,0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
} return (int)msg.wParam;
}LRESULT CALLBACK WndProc(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam)
{
switch(message)
{
case WM_CREATE:
hBitmap=LoadBitmap(((LPCREATESTRUCT)lParam)->hInstance,TEXT("FLAG"));
hwndBN=CreateWindow(TEXT("button"),NULL,BS_BITMAP|WS_CHILD|WS_VISIBLE,
15,15,15,15,hwnd,(HMENU)(0),NULL, NULL);
oldButton=(WNDPROC)SetWindowLong(hwndBN,GWL_WNDPROC,(long)ButtonProc);
return 0;
case WM_COMMAND:
return 0;
/*case WM_PAINT:
HDC hDC,hDCMem;
PAINTSTRUCT ps; hDC = BeginPaint(hwnd, &ps);
hDCMem = CreateCompatibleDC(hDC); SelectObject(hDCMem, (HBITMAP) hBitmap);
BitBlt(hDC, 0, 0, 12, 12, hDCMem, 0, 0, SRCCOPY); EndPaint(hwnd, &ps);
return 0;*/
case WM_DESTROY:
PostQuitMessage(0);
return 0;
}
return DefWindowProc(hwnd,message,wParam,lParam);
}LRESULT CALLBACK ButtonProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_RBUTTONDOWN:
SendMessage(hwnd,BM_SETIMAGE,IMAGE_BITMAP,(LPARAM)hBitmap);
break;
}
return CallWindowProc (oldButton, hwnd, message, wParam, lParam) ;
}

解决方案 »

  1.   

    先这样试试:
    case WM_PAINT:
        HDC    hDC,hDCMem;
        PAINTSTRUCT    ps;    hDC = BeginPaint(hwnd, &ps);
        hDCMem = CreateCompatibleDC(hDC);    HGDIOBJ oldBitmap = SelectObject(hDCMem, (HBITMAP) hBitmap);
        BitBlt(hDC, 0, 0, 12, 12, hDCMem, 0, 0, SRCCOPY);
        SelectObject(hDCMem, oldBitmap);
        DeleteDC(hDCMem);    EndPaint(hwnd, &ps);
        return 0;
      

  2.   

    略微改了下你的代码case WM_PAINT:
    HDC hDC,hDCMem;
    PAINTSTRUCT ps;
    hDC = BeginPaint(hwnd, &ps);
    hDCMem = CreateCompatibleDC(hDC);
    oldBitmap = SelectObject(hDCMem, (HBITMAP) hBitmap);//前面先声明了oldBitmap
    BitBlt(hDC, 0, 0, 12, 12, hDCMem, 0, 0, SRCCOPY); SelectObject(hDCMem, oldBitmap);
    DeleteDC(hDCMem); EndPaint(hwnd, &ps);
    return 0;
    成功了,还望解释一下为什么?如果按您的代码,会有错误
    error C2360: “oldBitmap”的初始化操作由“case”标签跳过
                  参见“oldBitmap”的声明我前面在网上也看过类似的代码,我用了,提示同样的错误
    难道是编译器的问题?我是VS2005我那边的完整的代码的错误是在哪儿呢?
      

  3.   

    对于switch 的case中,变量的定义要放到所有的case之前,不然会出现这个提示错误
      

  4.   

    你使用完画图等,需要恢复原来的SelectObject(hDCMem, oldBitmap); 
      

  5.   

    原本的代码没有选出位图和删除内存DC,只有第1次可以正常执行,由于WM_PAINT消息会有很多,所以就导致显示不正常了。
    case下面不允许定义变量,我写代码时没注意,按你的做法改到上面定义。
      

  6.   

    把WM_PAINT的处理代码改过后还有什么问题?
      

  7.   

    这个解决的是我实验程序的问题贴在C++区的那段代码还是不能显示图片
    WM_PAINT没加
      

  8.   

    你应该准备两张图,创建按钮是指定BS_BITMAP风格,运行过程中用BM_SETIMAGE消息修改图片。
      

  9.   

    一张创建时用,另一张是BM_SETIAMGE时用?
    必须创建时指定BS_BITMAP,不能中途修改为BS_BITMAP?
      

  10.   

    BM_SETSTYLE好象改不了,SetWindowLong可以改,但这样做不确定是否有不良影响,最好是开始就设置BS_BITMAP风格。
    两张图分别表示两种状态,如果什么都不显示也可以用NULL。