Eine (warscheinlich) dumme frage



  • Verzeiht, wenn das gefragt dumm ist.

    Ich habe folgenden Code

    static HWND hButton;
    static HBITMAP hBitmap=NULL;
    static BITMAP bmpbut;
    static HBRUSH hbr=NULL;
    
    switch (message)
    {
    case WM_CREATE: {
      hBitmap = (HBITMAP)LoadImage(GetModuleHandle(NULL), _T("Button4.3.bmp"),
                               IMAGE_BITMAP,0, 0,LR_DEFAULTCOLOR | LR_LOADFROMFILE);
    
      GetObject(hBitmap, sizeof(BITMAP), &bmpbut);
    
      hButton = CreateWindow(_T("BUTTON"), _T("Test"), WS_VISIBLE|WS_CHILD|BS_FLAT|BS_PUSHBUTTON|BS_OWNERDRAW,
                             20, 20, bmpbut.bmWidth+2, bmpbut.bmHeight+2, hWnd, (HMENU)IDC_BUTTON1, NULL, NULL);
    
      // Bitmap auf Button plazieren (nur bei BS_BITMAP)
      // SendMessage (hButton, BM_SETIMAGE, (WPARAM) IMAGE_BITMAP,(LPARAM)(HANDLE) hBitmap);
    
      hbr = CreateSolidBrush(RGB(255, 0, 255));        // Background Brush
      }
      break;
    
    case WM_DRAWITEM: {
      LPDRAWITEMSTRUCT pdis = (LPDRAWITEMSTRUCT) lParam;
      switch (pdis->CtlID){
         case IDC_BUTTON1:
              HDC hDC = GetDC(hButton);
              HDC hComDC = CreateCompatibleDC(hDC);
              SelectObject(hComDC, hBitmap);
              BitBlt(hDC, 1, 1, bmpbut.bmWidth, bmpbut.bmHeight, hComDC, 0, 0, SRCCOPY);
              DeleteObject(hComDC);
              ReleaseDC(hButton, hDC);
              break;
    
        }
    
        if(pdis->itemState & ODS_SELECTED)
           InvertRect (pdis->hDC, &pdis->rcItem); // wenn Button gedrückt invertieren
      }
      break;
    
    case WM_CTLCOLORBTN:
      return (LRESULT)hbr;
    

    Wie bekomme ich jetztz weitere Buttons dazu?
    Hoffentlich ist die Frage nicht zu dumm.

    LG Aaron



  • Also ich wollte das so Regeln

    #define IDC_BUTTON1 1
    #define IDC_BUTTON2 2
    
    LRESULT CALLBACK WndProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam) {
    static HWND hButton;
    static HBITMAP hBitmap=NULL;
    static BITMAP bmpbut;
    static HBRUSH hbr=NULL;
    static HWND hButton1;
    static HBITMAP hBitmap1=NULL;
    switch (Message)
    {
    case WM_CREATE: {
      hBitmap = (HBITMAP)LoadImage(GetModuleHandle(NULL), _T("Button4.3.bmp"),
                               IMAGE_BITMAP,0, 0,LR_DEFAULTCOLOR | LR_LOADFROMFILE);
    
      GetObject(hBitmap, sizeof(BITMAP), &bmpbut);
    
      hButton = CreateWindow(_T("BUTTON"), _T("Test"), WS_VISIBLE|WS_CHILD|BS_FLAT|BS_PUSHBUTTON|BS_OWNERDRAW,
                             20, 20, bmpbut.bmWidth, bmpbut.bmHeight, hwnd, (HMENU)IDC_BUTTON1, NULL, NULL);
    
    hBitmap1 = (HBITMAP)LoadImage(GetModuleHandle(NULL), _T("Button4.2.bmp"),
                IMAGE_BITMAP,0, 0,LR_DEFAULTCOLOR | LR_LOADFROMFILE);
    
    hButton1 = CreateWindow(_T("BUTTON"), _T("Test"), WS_VISIBLE|WS_CHILD|BS_FLAT|BS_PUSHBUTTON|BS_OWNERDRAW,
                             20, 200, bmpbut.bmWidth, bmpbut.bmHeight, hwnd, (HMENU)IDC_BUTTON2, NULL, NULL);
      // Bitmap auf Button plazieren (nur bei BS_BITMAP)
      // SendMessage (hButton, BM_SETIMAGE, (WPARAM) IMAGE_BITMAP,(LPARAM)(HANDLE) hBitmap);
    
      hbr = CreateSolidBrush(RGB(95, 95, 95));        // Background Brush
      }
      break;
    
    case WM_DRAWITEM: {
      LPDRAWITEMSTRUCT pdis = (LPDRAWITEMSTRUCT) lParam;
      switch (pdis->CtlID)
         case IDC_BUTTON1:{
              HDC hDC = GetDC(hButton);
              HDC hComDC = CreateCompatibleDC(hDC);
              SelectObject(hComDC, hBitmap);
              BitBlt(hDC, 0, 0, bmpbut.bmWidth, bmpbut.bmHeight, hComDC, 0, 0, SRCCOPY);
              DeleteObject(hComDC);
              ReleaseDC(hButton, hDC);}
              break;
    
              case IDC_BUTTON2:{
              HDC hDC = GetDC(hButton1);
              HDC hComDC = CreateCompatibleDC(hDC);
              SelectObject(hComDC, hBitmap1);
              BitBlt(hDC, 0, 0, bmpbut.bmWidth, bmpbut.bmHeight, hComDC, 0, 0, SRCCOPY);
              DeleteObject(hComDC);
              ReleaseDC(hButton1, hDC);}
              break;
    
        if(pdis->itemState & ODS_SELECTED)
           InvertRect (pdis->hDC, &pdis->rcItem); // wenn Button gedrückt invertieren
      }
      break;
    
    case WM_CTLCOLORBTN:
      return (LRESULT)hbr;
    

    Dann kommen folgende Errors.

    In function 'LRESULT WndProc(HWND, UINT, WPARAM, LPARAM)':|
    error: jump to case label [-fpermissive]|
    error:   crosses initialization of 'tagDRAWITEMSTRUCT* pdis'|
    

    Was mach ich falsch



  • Das Problem ist offenbar, das du deine Variable pdis an einer Stelle in einem switch definiert hast, die potentiell übersprungen werden kann; check mal ab, ob du auch überall richtig deine {} gemacht hast...

    switch (x)
    {
      case 1:
        int bla;
        break;
    
      case 2:
        break;  // Problem: wenn x == 2 ist, wird die Definition von bla übersprungen
    }
    


  • Da fehlt ein {

    LPDRAWITEMSTRUCT pdis = (LPDRAWITEMSTRUCT) lParam; 
      switch (pdis->CtlID) /* und zwar hier */
        case IDC_BUTTON1:{
    

    Tip:
    Bei folgendem Einrückungsstil/Klammerstil ist es viel einfacher zu erkennen wo { oder } fehlen:

    void Fun()
    {
        switch (x)
        {
        case 1:
            {
                SomeType var = SomeFunction();
                // ...
            }
            break;
        }
    
        if (y)
        {
            for (int i = 0; i < 100; i++)
            {
                if (z)
                     SingleLineWithoutBlockIsOkToo();
            }
        }
    }
    


  • Mmh okay das hat alles funktioniert.
    Allerdings gibt es nun ein neues Problem.

    Normalerweise, invertiere ich die Button Farbe wenn man draufklickt. Das ist jetzt nicht mehr der Fall.
    Woran liegt das?

    case WM_DRAWITEM: {
      LPDRAWITEMSTRUCT pdis = (LPDRAWITEMSTRUCT) lParam;
      switch (pdis->CtlID){
         case IDC_BUTTON1:{
              HDC hDC = GetDC(hButton);
              HDC hComDC = CreateCompatibleDC(hDC);
              SelectObject(hComDC, hBitmap);
              BitBlt(hDC, 0, 0, bmpbut.bmWidth, bmpbut.bmHeight, hComDC, 0, 0, SRCCOPY);
              DeleteObject(hComDC);
              ReleaseDC(hButton, hDC);}
              break;
    
              case IDC_BUTTON2:{
              HDC hDC = GetDC(hButton1);
              HDC hComDC = CreateCompatibleDC(hDC);
              SelectObject(hComDC, hBitmap1);
              BitBlt(hDC, 0, 0, bmpbut.bmWidth, bmpbut.bmHeight, hComDC, 0, 0, SRCCOPY);
              DeleteObject(hComDC);
              ReleaseDC(hButton1, hDC);}
              break;
    
        if(pdis->itemState & ODS_SELECTED)
           InvertRect (pdis->hDC, &pdis->rcItem); // wenn Button gedrückt invertieren
      }}
    


  • Der selbe Code, nur anders eingerückt:

    case WM_DRAWITEM:
    		{ 
    			LPDRAWITEMSTRUCT pdis = (LPDRAWITEMSTRUCT) lParam; 
    			switch (pdis->CtlID)
    			{ 
    			case IDC_BUTTON1:
    				{ 
    					HDC hDC = GetDC(hButton); 
    					HDC hComDC = CreateCompatibleDC(hDC); 
    					SelectObject(hComDC, hBitmap); 
    					BitBlt(hDC, 0, 0, bmpbut.bmWidth, bmpbut.bmHeight, hComDC, 0, 0, SRCCOPY); 
    					DeleteObject(hComDC); 
    					ReleaseDC(hButton, hDC);
    				} 
    				break; 
    
    			case IDC_BUTTON2:
    				{ 
    					HDC hDC = GetDC(hButton1); 
    					HDC hComDC = CreateCompatibleDC(hDC); 
    					SelectObject(hComDC, hBitmap1); 
    					BitBlt(hDC, 0, 0, bmpbut.bmWidth, bmpbut.bmHeight, hComDC, 0, 0, SRCCOPY); 
    					DeleteObject(hComDC); 
    					ReleaseDC(hButton1, hDC);
    				} 
    				break; 
    
    				if (pdis->itemState & ODS_SELECTED) 
    					InvertRect(pdis->hDC, &pdis->rcItem); // wenn Button gedrückt invertieren 
    			}
    		}
    

    Siehst du es jetzt?

    Was ich über Einrückungsstil/Klammerstil geschrieben habe hat schon seinen Grund.

    ps: Der Compiler müsste dir hier auch eine Warning geben. Irgendwas über "unreachable code". Warnings ignorieren ist auch keine gute Idee.



  • mmh ne hat auch nicht geholfen



  • Beschreib mal wie du meinst dass die Ausführung die Zeile if (pdis->itemState & ODS_SELECTED) erreichen soll.



  • Tja gute frage.

    Aber wenn ich nur einen button habe funktioniert ja alles. Warum nicht wenn ich 2 habe



  • Okay ich habe das Problem gelöst. Waren nur 2 kleine Wörter.

    break;
    // und
    break;
    


  • Nein, die break s sind da schon OK.

    Ich glaube dir fehlen einfach noch viel zu viele Grundlagen.

    Eine "korrekte" Lösung wäre:

    case WM_DRAWITEM:
            { 
                LPDRAWITEMSTRUCT pdis = (LPDRAWITEMSTRUCT) lParam; 
                bool invertIfSelected = false;
                switch (pdis->CtlID)
                { 
                case IDC_BUTTON1:
                    invertIfSelected = true;
                    { 
                        HDC hDC = GetDC(hButton); 
                        HDC hComDC = CreateCompatibleDC(hDC); 
                        SelectObject(hComDC, hBitmap); 
                        BitBlt(hDC, 0, 0, bmpbut.bmWidth, bmpbut.bmHeight, hComDC, 0, 0, SRCCOPY); 
                        DeleteObject(hComDC); 
                        ReleaseDC(hButton, hDC);
                    } 
                    break; 
    
                case IDC_BUTTON2:
                    invertIfSelected = true;
                    { 
                        HDC hDC = GetDC(hButton1); 
                        HDC hComDC = CreateCompatibleDC(hDC); 
                        SelectObject(hComDC, hBitmap1); 
                        BitBlt(hDC, 0, 0, bmpbut.bmWidth, bmpbut.bmHeight, hComDC, 0, 0, SRCCOPY); 
                        DeleteObject(hComDC); 
                        ReleaseDC(hButton1, hDC);
                    } 
                    break; 
                }
    
                if (invertIfSelected && (pdis->itemState & ODS_SELECTED))
                    InvertRect(pdis->hDC, &pdis->rcItem); // wenn Button gedrückt invertieren 
            }
    


  • Mmh nachdem ich aber die breaks; weggenommen habe, hat alles funktioniert



  • Ja, das ist mir schon klar.
    Trotzdem ist es Mist ohne die break s.

    Ist dir denn klar was ohne die break s passiert wenn das ganze mit pdis->CtlID == IDC_BUTTON1 ausgeführt wird?



  • ne warum?



  • Verstehst du überhaupt irgendwas davon was das Programm macht?



  • hustbaer schrieb:

    Verstehst du überhaupt irgendwas davon was das Programm macht?

    Die erste Frage war eigentlich schon Beweis genug, das dies nicht der Fall ist:

    https://www.c-plusplus.net/forum/331622-10

    Weitere Buttons waren als Kommentar schon vorgesehen ...


Log in to reply