各位高手!
小弟用如下方法可以在桌面上直接创建按钮
但是创建出的按钮不得到相应就像command消息不进消息循环一样,
想知道为什么,
和如何使它得到响应.hwndButton[i] = CreateWindow ( TEXT("button"), 
                                   "BS_PUSHBUTTON",
                                   WS_CHILD | WS_VISIBLE | button    [i].iStyle,
                                   cxChar,cyChar * (1 + 2 * i),
                                   20 * cxChar, 7 * cyChar / 4,
                                  0x00000134, (HMENU) i,
                                   ((LPCREATESTRUCT) lParam)->hInstance, NULL) ;
///////////////////////////////////////////////////以下是WndProc
LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
     static HWND  hwndButton[NUM] ;
     static RECT  rect ;
     static TCHAR szTop[]    = TEXT ("message            wParam       lParam"),
                  szUnd[]    = TEXT ("_______            ______       ______"),
                  szFormat[] = TEXT ("%-16s%04X-%04X    %04X-%04X"),
                  szBuffer[50] ;
     static int   cxChar, cyChar ;
     HDC          hdc ;
     PAINTSTRUCT  ps ;
     int          i ;
     
     switch (message)
     {
     case WM_CREATE :
          cxChar = LOWORD (GetDialogBaseUnits ()) ;
          cyChar = HIWORD (GetDialogBaseUnits ()) ;
          
          for (i = 0 ; i < NUM ; i++)
               hwndButton[i] = CreateWindow ( TEXT("button"), 
                                   button[i].szText,
                                   WS_CHILD | WS_VISIBLE | button[i].iStyle,
                                   cxChar,cyChar * (1 + 2 * i),
                                   20 * cxChar, 7 * cyChar / 4,
                                  0x00000134, (HMENU) i,
                                   ((LPCREATESTRUCT) lParam)->hInstance, NULL) ;
          return 0 ;
case WM_PAINT :
          InvalidateRect (hwnd, &rect, TRUE) ;
          
          hdc = BeginPaint (hwnd, &ps) ;
          SelectObject (hdc, GetStockObject (SYSTEM_FIXED_FONT)) ;
          SetBkMode (hdc, TRANSPARENT) ;
          
          TextOut (hdc, 24 * cxChar, cyChar, szTop, lstrlen (szTop)) ;
          TextOut (hdc, 24 * cxChar, cyChar, szUnd, lstrlen (szUnd)) ;
          
          EndPaint (hwnd, &ps) ;
          return 0 ;
          
     case WM_DRAWITEM :
     case WM_COMMAND :
          ScrollWindow (hwnd, 0, -cyChar, &rect, &rect) ;
          
          hdc = GetDC (hwnd) ;
          SelectObject (hdc, GetStockObject (SYSTEM_FIXED_FONT)) ;
          
          TextOut (hdc, 24 * cxChar, cyChar * (rect.bottom / cyChar - 1),
                   szBuffer,
                   wsprintf (szBuffer, szFormat,
                         message == WM_DRAWITEM ? TEXT ("WM_DRAWITEM") : 
                                                  TEXT ("WM_COMMAND"),
                         HIWORD (wParam), LOWORD (wParam),
                         HIWORD (lParam), LOWORD (lParam))) ;
          
          ReleaseDC (hwnd, hdc) ;
          ValidateRect (hwnd, &rect) ;
          break ;
          
     case WM_DESTROY :
          PostQuitMessage (0) ;
          return 0 ;
     }
     return DefWindowProc (hwnd, message, wParam, lParam) ;
}

解决方案 »

  1.   

    被你搞糊涂了.
    1. 这个WNDPROC是谁的WNDPROC?
    2. 桌面是什么意思? DESKTOP? 但根据你createwindow()的参数来看,明明是有父窗口的麻,其句柄是0x00000134.
    3. 0x00000134这个句柄到底是谁的?
    4. 既然使有BUTTON类,那么一般说来你只有在它的父窗口上处理消息.当button被点击时,父窗口收到WM_COMMAND清息.
    5. 为什么在你的WNDPROC中WM_COMMAND和WM_DRAWITEM的处理是共用的,WM_COMMAND可是个极复杂的消息啊!
      

  2.   

    预定义类创建的窗口只能用子类化的方法控制,子类化就是利用SetWindowLong函数替换窗口WindowProc为自己编写的SubclassProc,注意SubclassProc应该把不处理的消息通过CallWindowProc调用窗口原来的WindowProc
      

  3.   

    0x00000134就是桌面的窗口句柄
    这是用spy++查出来得
      

  4.   

    hwndButton[i] = CreateWindow ( TEXT("button"), 
                       button[i].szText,
                       WS_CHILD | WS_VISIBLE | button[i].iStyle,
                       cxChar,cyChar * (1 + 2 * i),
                       20 * cxChar, 7 * cyChar / 4,
                       0x00000134, (HMENU) i,//替换成hwnd,
                      ((LPCREATESTRUCT) lParam)->hInstance,
      

  5.   

    o,对不起,收回上面的贴,
    你可以用GetWindowLong获得桌面的处理过程。进行子类化。
      

  6.   

    利用SetWindowLong函数替换窗口WindowProc为自己编写的SubclassProc
      

  7.   

    用SPY++查DESKTOP的句柄? 我的天!机器不同,这个值是不同的,比如我机器上就是0x00010014,不要这样使用.如果你的父句柄是NULL,则代表DESKTOP.在DESKTOP是建按钮是可以的,你需要用GetWindowLong找到BUTTON的WNDPROC,用SetWindowLong将你的WNDPROC设成BUTTON的WNDPROC, 最需要注意是在你的WNDPROC中要将消息再导回BUTTON的原WNDPROC中,这样才能保证消息链的完整.但这样就有了问题,BUTTON 是不会自己摧毁自已,也就是说,倒底是谁将会告诉这些BUTTON应该结束了? 你的WNDPROC中有WM_QUIT,你想一想谁会向你的BUTTON中发这个消息呢? 你的WM_COMMAND消息将传递给DESKTOP,也就是说当你按动按钮是,这个消息到了DESKTOP那里,你难道准备让DESTKTOP处理你的按钮按动的消息?
      

  8.   

    对不起这是我修改后的全部程序为什么还是不行
    #include <windows.h>struct
    {
         int     iStyle ;
         TCHAR * szText ;
    }
    button[] =
    {
         BS_PUSHBUTTON,      TEXT ("PUSHBUTTON"),
         BS_DEFPUSHBUTTON,   TEXT ("DEFPUSHBUTTON"),
         BS_CHECKBOX,        TEXT ("CHECKBOX"), 
         BS_AUTOCHECKBOX,    TEXT ("AUTOCHECKBOX"),
         BS_RADIOBUTTON,     TEXT ("RADIOBUTTON"),
         BS_3STATE,          TEXT ("3STATE"),
         BS_AUTO3STATE,      TEXT ("AUTO3STATE"),
         BS_GROUPBOX,        TEXT ("GROUPBOX"),
         BS_AUTORADIOBUTTON, TEXT ("AUTORADIO"),
         BS_OWNERDRAW,       TEXT ("OWNERDRAW")
    } ;#define NUM (sizeof button / sizeof button[0])LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ;
    LRESULT CALLBACK CldWndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
                        PSTR szCmdLine, int iCmdShow)
    {
         static TCHAR szAppName[] = TEXT ("BtnLook") ;
         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  = NULL ;
         wndclass.lpszClassName = szAppName ;
         
         if (!RegisterClass (&wndclass))
         {
              MessageBox (NULL, TEXT ("This program requires Windows NT!"),
                          szAppName, MB_ICONERROR) ;
              return 0 ;
         }
         
         hwnd = CreateWindow (szAppName, TEXT ("Button Look"),
                              WS_OVERLAPPEDWINDOW,
                              CW_USEDEFAULT, CW_USEDEFAULT,
                              CW_USEDEFAULT, CW_USEDEFAULT,
                              NULL, NULL, hInstance, NULL) ;
         
         ShowWindow (hwnd, iCmdShow) ;
         UpdateWindow (hwnd) ;
         
         while (GetMessage (&msg, NULL, 0, 0))
         {
              TranslateMessage (&msg) ;
              DispatchMessage (&msg) ;
         }
         return msg.wParam ;
    }LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
    {
         static HWND  hwndButton[NUM] ;
         static RECT  rect ;
         static TCHAR szTop[]    = TEXT ("message            wParam       lParam"),
                      szUnd[]    = TEXT ("_______            ______       ______"),
                      szFormat[] = TEXT ("%-16s%04X-%04X    %04X-%04X"),
                      szBuffer[50] ;
         static int   cxChar, cyChar ;
         HDC          hdc ;
         PAINTSTRUCT  ps ;
         int          i ;
         
         switch (message)
         {
         case WM_CREATE :
              cxChar = LOWORD (GetDialogBaseUnits ()) ;
              cyChar = HIWORD (GetDialogBaseUnits ()) ;
              
              for (i = 0 ; i < NUM ; i++)
      {hwndButton[i] = CreateWindow ( TEXT("button"), 
                                       button[i].szText,
                                       WS_CHILD | WS_VISIBLE | button[i].iStyle,
                                       cxChar,cyChar * (1 + 2 * i),
                                       20 * cxChar, 7 * cyChar / 4,
                                       GetDesktopWindow(), (HMENU) i,
                        ((LPCREATESTRUCT) lParam)->hInstance, NULL) ;
     
             SetWindowLong(hwndButton[0],GWL_WNDPROC,WndProc);
      //ShowWindow (0x00000134, SW_SHOW);
      //UpdateWindow(hwndButton[i]);
      }
      //UpdateWindow(0x00000134);   return 0 ;     case WM_SIZE :
              rect.left   = 24 * cxChar ;
              rect.top    =  2 * cyChar ;
              rect.right  = LOWORD (lParam) ;
              rect.bottom = HIWORD (lParam) ;
              return 0 ;
              
         case WM_PAINT :
              InvalidateRect (hwnd, &rect, TRUE) ;
              
              hdc = BeginPaint (hwnd, &ps) ;
              SelectObject (hdc, GetStockObject (SYSTEM_FIXED_FONT)) ;
              SetBkMode (hdc, TRANSPARENT) ;
              
              TextOut (hdc, 24 * cxChar, cyChar, szTop, lstrlen (szTop)) ;
              TextOut (hdc, 24 * cxChar, cyChar, szUnd, lstrlen (szUnd)) ;
              
              EndPaint (hwnd, &ps) ;
              return 0 ;
              
         case WM_DRAWITEM :
         case WM_COMMAND :
              ScrollWindow (hwnd, 0, -cyChar, &rect, &rect) ;
              
              hdc = GetDC (hwnd) ;
              SelectObject (hdc, GetStockObject (SYSTEM_FIXED_FONT)) ;
              
              TextOut (hdc, 24 * cxChar, cyChar * (rect.bottom / cyChar - 1),
                       szBuffer,
                       wsprintf (szBuffer, szFormat,
                             message == WM_DRAWITEM ? TEXT ("WM_DRAWITEM") : 
                                                      TEXT ("WM_COMMAND"),
                             HIWORD (wParam), LOWORD (wParam),
                             HIWORD (lParam), LOWORD (lParam))) ;
              
              ReleaseDC (hwnd, hdc) ;
              ValidateRect (hwnd, &rect) ;
              break ;
              
         case WM_DESTROY :
              PostQuitMessage (0) ;
              return 0 ;
         }
         return DefWindowProc (hwnd, message, wParam, lParam) ;
    }
      

  9.   

    好像还没有弄懂:
    1. 你需要在DESKTOP上建按钮.
    2. 你需要按钮有动作.
    3. 你要在哪里显示? (即TEXTOUT到哪里去?)
    4. 什么时候销毁这些按钮?回答问题3,4,我帮你改.
      

  10.   

    问题3的答案显然是GetDesktopWindow()桌面窗口的句柄
    程序结束时销毁按钮
      

  11.   

    在桌面上显示文字?,可否在你WINMAIN()中创建的那个窗中显现你所需的文字?我从来没有在桌面显示文字过.程序何时结束?通常WINDOWS的程序在通过1.用户点击一个菜单, 2. 用户点击系统按钮(即那个有X的按钮),3. 用户按ALT+F4, 你是要哪一个?
    WIN32的程序不会自动退出的,因为你有个WHILE()无限循环,只有某个事件导致了WM_QUIT的出现才会使程序退出.
      

  12.   

    首先你要知道你将自己的按纽创建在了别人进程里面,所以消息都流到别人那里去了,你可以使用HOOK技术来完成这个想法。
    我曾经做过一个全仿照WINDOWS界面程序,我将自己的新建的假的开始按纽替换了WINDOWS真正的开始按纽,然后在我自己的程序里响应消息弹出菜单。
    我就是用MSG HOOK做的。不过具我所知,还有好多其它方法,但大都是与HOOK有关,只不过HOOK类型不同罢了!
    关于这方面有一个示例代码,相对比较复杂一点,是别人写的,在VC知识库可以下载到。它好象用的是API HOOK你去看看吧!