2016-03-27 3 views
-1

ich eine Ressource-Datei (RC), die die folgendenOrder of win32api Funktionen Callback-Funktion verursacht die gleiche Nachricht erhalten

#include <windows.h> 
#include "resource.h" 

IDD_ABOUT DIALOG DISCARDABLE 0, 0, 500, 106 
BEGIN 

    DEFPUSHBUTTON "&OK", IDOK,   174, 18, 50, 14 

    RADIOBUTTON  "Radio 1", ID_RADIOBUTTON1, 226, 18, 55, 14 
END 

Meine C-Datei enthält enthält folgende

#include <windows.h> 
#include "resource.h" 

BOOL CALLBACK AboutDlgProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam) 
{ 
    switch(Message) 
    { 
     case WM_COMMAND: 
     switch(LOWORD(wParam)) 
     { 
      case ID_RADIOBUTTON1: 
      { 
       MessageBox(hwnd, "RadioButton 1", "111", MB_OK); 
       SendMessage((HWND)lParam, (UINT) BM_SETCHECK, (WPARAM) BST_CHECKED,(LPARAM)NULL); 
      } 
     return TRUE; 
     break; 

     } 
    break; 
     default: 
      return FALSE; 
    } 
     return TRUE; 
} 

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, 
    LPSTR lpCmdLine, int nCmdShow) 
{ 
    DialogBox(GetModuleHandle(NULL), MAKEINTRESOURCE(IDD_ABOUT), NULL, AboutDlgProc); 
} 

Nach einem Klick Der Radio-Button einmal nach dem Öffnen des Dialogfelds hat die Rückruffunktion wiederholt die gleiche Nachricht, die ein WM_COMMAND mit dem LOWORD (wParam) == ID_RADIOBUTTON1 ist. Aber wenn SendMessage vor MessageBox aufgerufen wird, tritt der Fehler nicht auf. Gibt es einen bestimmten Grund dafür?

EDIT


Aber wenn ich den Anruf ersetzen mit printf MessageBox dann tritt der Fehler nicht passieren und das Verhalten ist wie erwartet, und nur eine einzige Instanz Ausgang erzeugt wird.

Ich benutze gcc und windres, um das Programm zu machen.

Mein Betriebssystem ist Windows Vista (tm) Home Premium 32-Bit Service Pack 2

+1

Sie verpassen ein Semikolon – stackptr

+0

Sorry ... ich es bearbeitet schlecht – user2419083

+1

Von halbe Meile entfernt, ohne es zu testen: BM_SETCHECK eine BN_CLICK Meldung generieren. Welches ist in eine WM_COMMAND-Benachrichtigung verpackt. Wenn Sie also den SendMessage-Aufruf verschieben, können Sie wählen, ob Sie 100% des Kerns im Benutzeroberflächenthread brennen oder einen Bildschirm mit Nachrichtenfeldern füllen möchten. Brechen Sie die Schleife, indem Sie nur BM_SETCHECK senden, wenn der Radiobutton * * überprüft werden muss. So ähnlich. –

Antwort

0

Verwenden AUTORADIOBUTTON (statt RADIOBUTTON) Dies wird die Auswahlmarke automatisch eingestellt. Zum Beispiel:

IDD_ABOUT DIALOGEX 0, 0, 222, 257 
STYLE DS_ABSALIGN | DS_SETFONT | WS_POPUP | WS_CLIPCHILDREN | WS_CAPTION | WS_SYSMENU 
CAPTION "Dialog" 
FONT 9, "Segoe UI", 400, 0, 0x0 
BEGIN 
    DEFPUSHBUTTON "&OK", IDOK, 174, 18, 50, 14 
    AUTORADIOBUTTON "Radio 1", ID_RADIOBUTTON1, 226, 18, 55, 14 
END 

können Sie MessageBox oder andere modale Fenster verwenden:

... 
case ID_RADIOBUTTON1: 
{ 
    MessageBox... 
} 

für RADIOBUTTON Sie die Auswahl markieren Sie sich einstellen müssen. Tun Sie dies so schnell wie möglich und senden Sie sofort TRUE zurück. Rufen Sie MessageBox nicht vor oder nach:

case ID_RADIOBUTTON1: 
    SendMessage((HWND)lParam, BM_SETCHECK, !IsDlgButtonChecked(hwnd, ID_RADIOBUTTON1), 0); 
    return TRUE; 
+0

PS, in Visual Studio 2015 konnte ich nicht die gleichen Fehler duplizieren (ich habe einige Fehler/Fehlverhalten dupliziert) Vielleicht verwenden Sie eine andere IDE. –

+0

Aber warum nicht MessageBox anrufen, gibt es einen bestimmten Grund, dies nicht zu tun? Siehe auch meine Bearbeitung in der Frage für weitere Informationen. – user2419083

+0

Ich konnte Ihren Fehler in Visual Studio 2008 duplizieren ----- Sie sollten '" AUTORADIOBUTTON "' verwenden, dann können Sie eine 'MessageBox' verwenden. Das Problem ist, dass Sie "RADIOBUTTON" verwenden, was alt ist. Wenn Sie die Auswahl als Reaktion auf die Auswahl festlegen, kann dies leicht in einer Schleife hängen bleiben. –