在一个父窗口上要创建多个自定义的同类型的子控件,如何给每个子控件创建一个回调函数,那会很麻烦.能不能给这些子控件共用一个回调函数呢?如果共用一个回调函数怎么实现这些子控件的重绘,还有比如发生了单击事件,如何知道是哪个子控件发出的?

解决方案 »

  1.   

    WM_PAINT 和 WM_create肯定是无法区分的  按钮的话你确定不同的ID号进行消息相应就行了
      

  2.   

    最简单的办法:用SendMessage,子控件给父窗体发消息,用自定义消息ID来区分不同的子控件,然后在父窗体的WindowsProc里面处理这些消息。
      

  3.   

    #define WIN32_LEAN_AND_MEAN
    #include <windows.h>
    #include <windowsx.h>
    #define WINDOW_CLASS_NAME "WINCLASS"
    LRESULT CALLBACK WindowProc(HWND,UINT,WPARAM,LPARAM);
    LRESULT CALLBACK MyBtProc(HWND,UINT,WPARAM,LPARAM);
    void InitMyButton(HINSTANCE hinstance,HWND hwnd);
    //static HDC hdc,hdcmen;
    //static HBITMAP hbtmap;
    HWND hmybt[9];
    static int pos[9][2]={0,0,1,0,2,0,0,1,1,1,2,1,0,2,1,2,2,2};  //存储各小块图片的左上角坐标int WINAPI WinMain (HINSTANCE hinstance, HINSTANCE hprevinstance,                   PSTR szcmdLine, int icmdshow){

    HWND       hwnd;
    MSG        msg;
    WNDCLASSEX winclass; winclass.cbSize       = sizeof(WNDCLASSEX);
    winclass.style        = CS_DBLCLKS|CS_OWNDC|CS_HREDRAW|CS_VREDRAW;
    winclass.lpfnWndProc  = WindowProc;
    winclass.cbClsExtra   = 0;
    winclass.cbWndExtra   = 0;
    winclass.hInstance    = hinstance;
    winclass.hIcon        = LoadIcon(NULL,IDI_APPLICATION);
    winclass.hCursor      = LoadCursor(NULL,IDC_ARROW);
    winclass.hbrBackground= GetStockObject(WHITE_BRUSH);
    winclass.lpszMenuName = NULL;
    winclass.lpszClassName= WINDOW_CLASS_NAME;
    winclass.hIconSm      = LoadIcon(NULL,IDI_APPLICATION); if(!RegisterClassEx(&winclass))
    return (0); if(!(hwnd = CreateWindowEx(NULL,
                           WINDOW_CLASS_NAME,
       "WinFormPrj",
       WS_MINIMIZEBOX|WS_SYSMENU|WS_VISIBLE,
                                   440,312,
       400,400,
                                   NULL, 
       NULL, 
       hinstance, 
       NULL)))
    return (0); InitMyButton(hinstance,hwnd);
    while(GetMessage(&msg,NULL,0,0))
    {
    TranslateMessage(&msg);
    DispatchMessage(&msg);
    } return(msg.wParam);}void InitMyButton(HINSTANCE hinst,HWND hwnd)
    {
    WNDCLASSEX winclass;
    int i; winclass.cbSize       = sizeof(WNDCLASSEX);
    winclass.style        = CS_HREDRAW|CS_VREDRAW;
    winclass.lpfnWndProc  = MyBtProc;
    winclass.cbClsExtra   = 0;
    winclass.cbWndExtra   = 0;
    winclass.hInstance    = hinst;
    winclass.hIcon        = LoadIcon(NULL,IDI_APPLICATION);
    winclass.hCursor      = LoadCursor(NULL,IDC_ARROW);
    winclass.hbrBackground= GetStockObject(WHITE_BRUSH);
    winclass.lpszMenuName = NULL;
    winclass.lpszClassName= "MyButton";
    winclass.hIconSm      = LoadIcon(NULL,IDI_APPLICATION); RegisterClassEx(&winclass); for(i=0;i<9;i++)
    {
    hmybt[i]=CreateWindow("MyButton",
                    NULL,
                    WS_BORDER|WS_CHILD|WS_VISIBLE,
                    pos[i][0]*131,pos[i][1]*122,
                    131,122,
                    hwnd,
                    NULL,
                    hinst,
    NULL);
    }
    }LRESULT CALLBACK MyBtProc(HWND hwnd,UINT msg,WPARAM wparam,LPARAM lparam)
    {
    HDC hdcpaint;
    PAINTSTRUCT ps;
    static HDC hdc,hdcmen;
    static HBITMAP hbtmap;
    int i;      //循环变量
    //int px,py;  //贴图左上角坐标
    //static int pos[9][2]={0,0,1,0,2,0,0,1,1,1,2,1,0,2,1,2,2,2};  //存储各小块图片的左上角坐标 switch(msg)
    {
        case WM_CREATE:
    {
        hdc=GetDC(hwnd);
    hdcmen=CreateCompatibleDC(hdc);
    hbtmap=(HBITMAP)LoadImage(NULL,"kitty.bmp",IMAGE_BITMAP,393,366,LR_LOADFROMFILE);  
                SelectObject(hdcmen,hbtmap);


    return 0;
    }break;

    case WM_PAINT:
    {
    for(i=0;i<9;i++)
    {
    hdcpaint=BeginPaint(hmybt[i],&ps);
        BitBlt(hdc,0,0,131,122,hdcmen,pos[i][0]*131,pos[i][1]*122,SRCCOPY);
                    BitBlt(hdcpaint,0,0,131,122,hdc,0,0,SRCCOPY);
    EndPaint(hmybt[i],&ps);
    }

    return 0;
    }break; case WM_LBUTTONDOWN:
    {

    return 0;
    }break; case WM_DESTROY:
    {
    DeleteObject(hbtmap);
    DeleteDC(hdc);
    DeleteDC(hdcmen); PostQuitMessage(0);
    return 0;
    }break;
    }
    return (DefWindowProc(hwnd,msg,wparam,lparam));
    }LRESULT CALLBACK WindowProc(HWND hwnd,UINT msg,WPARAM wparam,LPARAM lparam)
    { switch(msg)
    {
        /*case WM_CREATE:
    { return (0);
    }*/
        

            case WM_DESTROY:
    {
    PostQuitMessage(0);
    return (0);
    } break; default:break;
    }
    return (DefWindowProc(hwnd,msg,wparam,lparam));
    }
    就是这个程序,为什么在重绘子控件时出现问题,当其他窗口拖动过这些子窗口控件时没有发生重绘