Button mit Visual Styles



  • Moin,

    ich lerne gerade etwas WinAPI und bin bei Steuerelementen angelangt, soweit alles kein Problem. Nun möchte ich gerne dass die Buttons auch den typischen Vista-Style haben und nicht ausschauen als hätte ich einen Windows 3.11 Emulator geschrieben.

    Der Button wird bei mir richtig angezeigt, aber es passiert nichts wenn ich ihn anklicke, also es ist nicht die Animation zu sehen wie sie bei den alten Buttons angezeigt wird. Ich bekomme also keine visuelle Rückmeldung dass ich den Button angeklickt habe, so wie bei den alten Buttons ohne Visual Styles.

    Kann mir wer da weiterhelfen?

    Hier mal der Testcode unter Visual Studio 2008 prof. unter Vista 32bit SP2:

    #include <windows.h>
    #include <commctrl.h>
    #include "tchar.h"
    
    #pragma comment(lib, "comctl32.lib")
    
    #pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='x86' publicKeyToken='6595b64144ccf1df' language='*'\"")
    
    HINSTANCE button_instance;
    
    LRESULT CALLBACK WndProc (HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) 
    {
      HWND button;
      switch (message) 
      {
        case WM_CREATE:
          button = CreateWindow(_T("BUTTON"), _T("Visual Style"),
                                     WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON,
                                     16, 16, 160, 32,
                                     hWnd, (HMENU) 1,
                                     button_instance, NULL);
        return 0;
    
        case WM_PAINT:
        return 0;
    
        case WM_DESTROY:
          PostQuitMessage(0); 
        return 0;
      }
      return DefWindowProc (hWnd, message, wParam, lParam);
    }
    
    int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int iCmdShow) 
    {
      HWND     hwnd;     
      MSG      msg;      
      WNDCLASS wndclass; 
      TCHAR _app_name[] =_T("visualstyle");
    
      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 = _app_name; 
    
      InitCommonControls();
    
      if (!RegisterClass (&wndclass))     
      {
        MessageBox (NULL, _T("Programm läuft nur mit Unicode und arbeitet erst unter Windows NT,2000,XP,Vista oder 7!"), _app_name, MB_ICONERROR);
        return 0;
      }
    
      hwnd = CreateWindow (       
             _app_name,           
             _app_name,           
             WS_OVERLAPPEDWINDOW, 
             CW_USEDEFAULT,       
             CW_USEDEFAULT,       
             640,                 
             512,                
             NULL,                
             NULL,                
             hInstance,           
             NULL);               
    
      ShowWindow(hwnd, iCmdShow); 
      UpdateWindow(hwnd);         
    
      while (GetMessage (&msg, NULL, 0, 0)) 
      {
        TranslateMessage(&msg);   
        DispatchMessage(&msg);  
      }
    
      return msg.wParam; 
    }
    




  • Die FAQ habe ich gelesen und denke ich habe auch alles davon eingebaut. Da ich nicht alle Architekturen zum Lernen unterstützen möchte habe ich auf die bedingten Linkerzusätze verzichtet.

    Aber auch wenn ich es genauso einbauen bleibt das Ergebnis gleich.

    Wer kennt sich aus und kann mir den entscheidenden Tipp geben?



  • Bei mir wird der Button in XP-Style angezeigt.



  • Ja bei mir wird der Button ja auch im richtigen Style angezeigt, nur kann ich ihn nicht anklicken, also man sieht beim Anklicken nicht diesen typischen runtergedrückten Zustand des Buttons.



  • WM_PAINT bearbeiten

    case WM_PAINT:
        hdc = BeginPaint(hWnd, &ps);
        ....
        EndPaint(hWnd, &ps);
    return 0;
    

    und bei

    HWND button;
    

    noch

    PAINTSTRUCT ps;
    HDC hdc;
    

    dann müsste das gehen.

    LRESULT CALLBACK WndProc (HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
    {
      HWND hwndButton;
      PAINTSTRUCT ps;
      HDC hdc;
      switch (message)
      {
        case WM_CREATE:
          hwndButton = CreateWindow(_T("BUTTON"), _T("Visual Style"),
                                     WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON,
                                     16, 16, 160, 32,
                                     hWnd, (HMENU) 1,
                                     button_instance, NULL);
        return 0;
    
        case WM_PAINT:
    		hdc = BeginPaint(hWnd, &ps);
    		//....
    		EndPaint(hWnd, &ps);
        return 0;
    
        case WM_DESTROY:
          PostQuitMessage(0);
        return 0;
      }
      return DefWindowProc (hWnd, message, wParam, lParam);
    }
    


  • Vielen, vielen, vielen Dank,

    du hast meinen Tag gerettet, das hat mich heute die ganze Zeit gewurmt :D.

    Hat wer eine Erklärung warum es nur mit einem BeginPaint und EndPaint in WM_PAINT funktioniert? Bei den alten Styles macht es keinen Unterschied.



  • Weil dein Fenster durch den klick neu gezeichnet werden muss.
    Ich empfehle die das Buch von "Charles Petzold" "Windows Programmierung", dort ist alles bestens erklärt.

    Ich kann dir auch nur raten deine WinAPI-code mit MS VC 2008 erstellen zu lassen, dort ist alles enthalten, auch ein *.rc die du mitr einen Ressourceneditor bearbeiten kannst und somit dein Dialog erstellst.



  • Sillo schrieb:

    Weil dein Fenster durch den klick neu gezeichnet werden muss.

    Hmm, beim "normalen" Style wird doch auch neu gezeichnet und dort klappt es ohne Funktionsaufrufe durch WM_PAINT. Wie erklärt sich das?

    Sillo schrieb:

    Ich empfehle die das Buch von "Charles Petzold" "Windows Programmierung", dort ist alles bestens erklärt.

    Von dem Werk habe ich auch nur gutes gelesen und es wird sicherlich mal einen Weg in die Regale finden.

    Sillo schrieb:

    Ich kann dir auch nur raten deine WinAPI-code mit MS VC 2008 erstellen zu lassen, dort ist alles enthalten, auch ein *.rc die du mitr einen Ressourceneditor bearbeiten kannst und somit dein Dialog erstellst.

    Ich mache immer gerne viel zu Fuß bevor ich irgendwelche Assistenten benutze. Mir geht es nicht darum so schnell und unkompliziert wie möglich eine Anwendung zusammen zu klicken sondern darum Windows-Anwendungen so nah am Kernel wie möglich zu entwickeln.

    Wenn es schnell gehen sollte würde ich eh viel mit C#/.NET machen, aber das interessiert mich im Moment nicht. Mich begeisterst zur Zeit theoretische Informatik, C, Datenstrukturen und Algorithmen und die WinAPI weil ich schon immer mal unter der Haube werkeln wollte 😉



  • justchris schrieb:

    Hmm, beim "normalen" Style wird doch auch neu gezeichnet und dort klappt es ohne Funktionsaufrufe durch WM_PAINT. Wie erklärt sich das?

    Bei mir nicht.

    Ich mache immer gerne viel zu Fuß bevor ich irgendwelche Assistenten benutze. Mir geht es nicht darum so schnell und unkompliziert wie möglich eine Anwendung zusammen zu klicken sondern darum Windows-Anwendungen so nah am Kernel wie möglich zu entwickeln.

    Das ist für mich zu Fuß gewesen und unkompliziert wird es dadurch auch nicht.



  • Ok, dann zeigt sich mein Fehler immer unter WindowsXP aber nicht immer unter Vista...sehr interessant. Könnte man noch näher nachgehen aber ich möchte hier einen Cut machen, die Lebenszeit is schließlich begrenzt 😃

    Ich danke dir jedenfalls für deine Hilfe auch wenn wir unter "zu Fuß" was anderes verstehen 😉

    Beste Grüße
    Chris


Anmelden zum Antworten