Das deutsche QBasic- und FreeBASIC-Forum Foren-Übersicht Das deutsche QBasic- und FreeBASIC-Forum
Für euch erreichbar unter qb-forum.de, fb-forum.de und freebasic-forum.de!
 
FAQFAQ   SuchenSuchen   MitgliederlisteMitgliederliste   BenutzergruppenBenutzergruppen  RegistrierenRegistrieren
ProfilProfil   Einloggen, um private Nachrichten zu lesenEinloggen, um private Nachrichten zu lesen   LoginLogin
Zur Begleitseite des Forums / Chat / Impressum
Aktueller Forenpartner:

Rechtsklick auf Checkbox ermöglichen (MFC/WinAPI)

 
Neues Thema eröffnen   Neue Antwort erstellen    Das deutsche QBasic- und FreeBASIC-Forum Foren-Übersicht -> Computer-Forum
Vorheriges Thema anzeigen :: Nächstes Thema anzeigen  
Autor Nachricht
Jojo
alter Rang


Anmeldungsdatum: 12.02.2005
Beiträge: 9736
Wohnort: Neben der Festplatte

BeitragVerfasst am: 06.01.2010, 00:21    Titel: Rechtsklick auf Checkbox ermöglichen (MFC/WinAPI) Antworten mit Zitat

Hi,
da es hier primär um C++ geht, poste ich mal im Computer-Forum. Ich habe eine Checkbox auf einem Dialog und möchte nun auch den Rechtsklick (und später auch Mittellklick) auf diese abfragen. In VB ging das ja recht einfach, aber die MFC-Komponenten scheinen sowas nicht zu bieten. Deswegen versuche ich jetzt irgendwie, den Rechtsklick selbst abzufangen und auszuwerten. Das ON_WM_RBUTTONDOWN-Event trifft leider nur ein, wenn ich direkt auf das Fenster einen Rechtsklick mache, ein Rechtsklick auf Kindelemente wird da nicht registriert.
Weiß jemand, wie ich solche Events mit der WinAPI oder MFC auswerten kann? Oder hat jemand lust, den Code nacht Qt zu portieren? Zunge rausstrecken
_________________
» Die Mathematik wurde geschaffen, um Probleme zu lösen, die es nicht gäbe, wenn die Mathematik nicht erschaffen worden wäre.


Zuletzt bearbeitet von Jojo am 06.01.2010, 18:39, insgesamt einmal bearbeitet
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden Website dieses Benutzers besuchen
Sebastian
Administrator


Anmeldungsdatum: 10.09.2004
Beiträge: 5969
Wohnort: Deutschland

BeitragVerfasst am: 06.01.2010, 01:15    Titel: Re: Rechtsklick auf Checkbox ermöglichen (MFC/WinAPI) Antworten mit Zitat

Kleine Frage am Rande:
Jojo hat Folgendes geschrieben:
Oder hat jemand lust, den Code nacht Qt zu portieren? Zunge rausstrecken

Es geht doch wahrscheinlich "bloß" um den gesamten Modplug-Source oder? lachen
_________________

Die gefährlichsten Familienclans | Opas Leistung muss sich wieder lohnen - für 6 bis 10 Generationen!
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden Website dieses Benutzers besuchen
Stueber



Anmeldungsdatum: 07.07.2008
Beiträge: 202

BeitragVerfasst am: 06.01.2010, 01:21    Titel: Antworten mit Zitat

Wenn ich wüsste um was es geht würde ichs mir aufjedenfall anschauen.
Aus Sebastians Beitrag schließe ich das es viel ist. lächeln
Aber grundsätzlich sinnvoll, nicht jeder hat MFC.
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
Stueber



Anmeldungsdatum: 07.07.2008
Beiträge: 202

BeitragVerfasst am: 06.01.2010, 01:25    Titel: Antworten mit Zitat

Wenn auch Winapi geht:
Du nimmst dir mit GetClassLongPtr den Zeiger auf die Windowfunktion der Checkbox und speicherst diesen.
Dann fügst du den Zeiger auf eine eigene Windowfunktion mit SetClassLongPtr ein.
Diese wertet dann WM_RBUTTONDOWN aus.
Wenn eine andere Nachricht als WM_RBUTTONDOWN reinkommt gibst du die einfach an die originale Windowfunktion weiter, deren Zeiger du ja gespeichert hast.


Zuletzt bearbeitet von Stueber am 06.01.2010, 02:22, insgesamt einmal bearbeitet
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
Stueber



Anmeldungsdatum: 07.07.2008
Beiträge: 202

BeitragVerfasst am: 06.01.2010, 02:15    Titel: Antworten mit Zitat

Hier das Beispiel:

Code:
#include "windows.bi"

dim shared func_pointer as function(byval hWnd as HWND, byval wMsg as UINT, byval wParam as WPARAM, byval lParam as LPARAM) as LRESULT

function WndProc ( byval hWnd as HWND, _
                   byval wMsg as UINT, _
                   byval wParam as WPARAM, _
                   byval lParam as LPARAM ) as LRESULT
   
    function = 0
   
    select case( wMsg )
        case WM_CREATE
            exit function
         

       case WM_DESTROY
            PostQuitMessage( 0 )
            exit function
    end select
   
    function = DefWindowProc( hWnd, wMsg, wParam, lParam )   
   
end function




function WndProc_Check ( byval hWnd as HWND, _
                   byval wMsg as UINT, _
                   byval wParam as WPARAM, _
                   byval lParam as LPARAM ) as LRESULT
   
    if wMsg = WM_RBUTTONDOWN then
        MessageBox(0,"Checkbox wurde geklickt mit der rechten Maustaste!","Nachricht!",MB_OK)
    end if
   
   
    function = func_pointer( hWnd, wMsg, wParam, lParam )   
   
end function





dim wMsg as MSG
dim wcls as WNDCLASS
dim hInstance as HINSTANCE
dim hPrevInstance as HINSTANCE
dim szCmdLine as string
dim iCmdShow as integer

hInstance = GetModuleHandle(null)
hPrevInstance = 0
szCmdLine = command()
iCmdShow = SW_NORMAL
with wcls
  .style         = CS_HREDRAW or CS_VREDRAW
  .lpfnWndProc   = @WndProc
  .cbClsExtra    = 0
  .cbWndExtra    = 0
  .hInstance     = hInstance
  .hIcon         = LoadIcon(NULL, IDI_APPLICATION)
  .hCursor       = LoadCursor(NULL, IDC_ARROW)
  .hbrBackground = CreateSolidBrush(GetSysColor(COLOR_BTNFACE))
  .lpszMenuName  = NULL
  .lpszClassName = @"Fenster"
end with

if(RegisterClass(@wcls) = FALSE) then
  MessageBox(null, "Die Fensterklasse konnte nicht registriert werden.", "Fehler", MB_ICONERROR)
  end
end if

dim as HWND h = CreateWindowEx(0, @"Fenster", "TEST", WS_OVERLAPPEDWINDOW,CW_USEDEFAULT, CW_USEDEFAULT, 200,100, NULL, NULL, GetModuleHandle(null), NULL)
dim as HWND c = CreateWindowEx(0, @"BUTTON", "Checkbox", WS_CHILD or WS_VISIBLE or BS_AUTOCHECKBOX,10, 10, 85, 40, h, NULL, GetModuleHandle(null), NULL)
func_pointer = GetWindowLongPtr(c,GWL_WNDPROC)
SetWindowLongPtr(c,GWL_WNDPROC,cast(DWORD,@WndProc_Check))

ShowWindow(h,SW_SHOW)
UpdateWindow(h)

while( GetMessage(@wMsg, NULL, 0, 0) <> FALSE)
  TranslateMessage(@wMsg)
  DispatchMessage(@wMsg)
wend



Oder in C++ als Unicode Version:
Code:
#include <windows.h>



LRESULT (*func_pointer)(HWND hWnd, UINT wMsg, WPARAM wParam, LPARAM lParam);

LRESULT CALLBACK WndProc ( HWND hWnd, UINT wMsg, WPARAM wParam, LPARAM lParam )
{
    switch( wMsg )
    {
    case WM_CREATE:
        return 0;


    case WM_DESTROY:
        PostQuitMessage( 0 );
        return 0;
    }

    return DefWindowProc( hWnd, wMsg, wParam, lParam );

}




LRESULT WndProc_Check ( HWND hWnd, UINT wMsg, WPARAM wParam, LPARAM lParam )
{

    if (wMsg == WM_RBUTTONDOWN)
    {
        MessageBox(0,L"Checkbox wurde geklickt mit der rechten Maustaste!",L"Nachricht!",MB_OK);
    }


    return func_pointer( hWnd, wMsg, wParam, lParam );

}





int main(int argc, char *argv[])
{
    MSG wMsg ;
    WNDCLASS wcls;
    HINSTANCE hInstance;
    HINSTANCE hPrevInstance;

    hInstance = GetModuleHandle(0);
    hPrevInstance = 0;

    wcls.style         = CS_HREDRAW | CS_VREDRAW;
    wcls.lpfnWndProc   = &WndProc;
    wcls.cbClsExtra    = 0;
    wcls.cbWndExtra    = 0;
    wcls.hInstance     = hInstance;
    wcls.hIcon         = LoadIcon(NULL, IDI_APPLICATION);
    wcls.hCursor       = LoadCursor(NULL, IDC_ARROW);
    wcls.hbrBackground = CreateSolidBrush(GetSysColor(COLOR_BTNFACE));
    wcls.lpszMenuName  = NULL;
    wcls.lpszClassName = L"Fenster";

    if(RegisterClass(&wcls) == FALSE)
    {
      MessageBox(0, L"Die Fensterklasse konnte nicht registriert werden.", L"Fehler", MB_ICONERROR);
      return 1;
    }


    HWND h = CreateWindowEx(0, L"Fenster", L"TEST", WS_OVERLAPPEDWINDOW,CW_USEDEFAULT, CW_USEDEFAULT, 200,100, NULL, NULL, GetModuleHandle(0), NULL);
    HWND c = CreateWindowEx(0, L"BUTTON", L"Checkbox", WS_CHILD | WS_VISIBLE | BS_AUTOCHECKBOX,10, 10, 85, 40, h, NULL, GetModuleHandle(0), NULL);
    func_pointer = (LRESULT(*)(HWND,UINT,WPARAM,LPARAM))GetWindowLongPtr(c,GWL_WNDPROC);
    SetWindowLongPtr(c,GWL_WNDPROC,(DWORD)WndProc_Check);

    ShowWindow(h,SW_SHOW);
    UpdateWindow(h);

    while( GetMessage(&wMsg, NULL, 0, 0) != FALSE)
    {
      TranslateMessage(&wMsg);
      DispatchMessage(&wMsg);
    }
    return 0;
}


Du brauchst nur den HWND der Checkbox, dann kannst du es auch so machen.
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
Jojo
alter Rang


Anmeldungsdatum: 12.02.2005
Beiträge: 9736
Wohnort: Neben der Festplatte

BeitragVerfasst am: 06.01.2010, 11:44    Titel: Antworten mit Zitat

Danke, das werde ich heute abend mal ausprobieren.
Und ja, es geht um den ModPlug und ja, es ist viel Arbeit (auch wenn ModPlug wesentlich mehr als nur die GUI ist). Zunge rausstrecken Aber je mehr mitmachen, desto weniger ist es für jeden und im Moment wären wir wohl 3-4 Leute, die den Code umbauen können/wollen.
_________________
» Die Mathematik wurde geschaffen, um Probleme zu lösen, die es nicht gäbe, wenn die Mathematik nicht erschaffen worden wäre.
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden Website dieses Benutzers besuchen
28398



Anmeldungsdatum: 25.04.2008
Beiträge: 1917

BeitragVerfasst am: 06.01.2010, 21:37    Titel: Antworten mit Zitat

Ich habe mir jetzt den Thread nicht durchgelesen, aber Subclassing wäre denke ich die beste Möglichkeit das zu realisieren.

//Lol sehe gerade, dass Stueber das schon geschrieben hat (Themenüberblick)
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
Jojo
alter Rang


Anmeldungsdatum: 12.02.2005
Beiträge: 9736
Wohnort: Neben der Festplatte

BeitragVerfasst am: 08.01.2010, 20:33    Titel: Antworten mit Zitat

Hmm, so ganz funktioniert das noch nicht. Den nötigen Code habe ich mal übernommen, aber in der Zeile "return func_pointer( hWnd, wMsg, wParam, lParam );" gibt's ne access violation... Habe im Code ein paar Sachen geändert (das muss LONG_PTR sein, nicht DWORD), aber auch unmodifiziert tritt der Fehler auf...

Code:
   HWND c = GetDlgItem(m_nCleanupIDtoDlgID[CU_REMOVE_INSTRUMENTS])->m_hWnd;
   func_pointer = (LRESULT(*)(HWND,UINT,WPARAM,LPARAM))GetWindowLongPtr(c, GWLP_WNDPROC);
   SetWindowLongPtr(c, GWLP_WNDPROC, (LONG_PTR)WndProc_Check);

Der pointer is auch nicht 0...

Mal weitersuchen...
_________________
» Die Mathematik wurde geschaffen, um Probleme zu lösen, die es nicht gäbe, wenn die Mathematik nicht erschaffen worden wäre.
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden Website dieses Benutzers besuchen
28398



Anmeldungsdatum: 25.04.2008
Beiträge: 1917

BeitragVerfasst am: 08.01.2010, 21:25    Titel: Antworten mit Zitat

Hast du den Pointer auf Null beim Setzen oder vor dem Aufruf geprüft?
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
Jojo
alter Rang


Anmeldungsdatum: 12.02.2005
Beiträge: 9736
Wohnort: Neben der Festplatte

BeitragVerfasst am: 08.01.2010, 21:28    Titel: Antworten mit Zitat

Der Pointer änder sich doch nicht von selbst... mit den Augen rollen Und nein, er war in keinem von beiden Fällen null.
_________________
» Die Mathematik wurde geschaffen, um Probleme zu lösen, die es nicht gäbe, wenn die Mathematik nicht erschaffen worden wäre.
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden Website dieses Benutzers besuchen
28398



Anmeldungsdatum: 25.04.2008
Beiträge: 1917

BeitragVerfasst am: 09.01.2010, 16:28    Titel: Antworten mit Zitat

Naja das kommt ganz auf den Stil an zwinkern
Wenn man bei einem Vergleich die Konstante rechts schreibt, und statt einem doppelten Gleichzeichen nur ein einfaches verwendet, setzt man die Variable auf diesem Wert. Beim GCC muss man explizit Warnungen bei Wertzuweisungen in if-Statements aktivieren. (Ich weiß nicht, ob der VC++ Compiler von sich aus derartige Warnungen generiert). Deswegen habe ich es mir angewöhnt die Konstante links zu schreiben, denn eine Wertzuweisung an eine Konstante produziert logischerweise einen Fehler.

B2T

Installiere mal OllyDbg und schau mal nach, wohin der Zeiger denn zeigt. Tritt der Fehler nur außerhalb oder nur innerhalb der IDE auf? Oder immer?
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
Jojo
alter Rang


Anmeldungsdatum: 12.02.2005
Beiträge: 9736
Wohnort: Neben der Festplatte

BeitragVerfasst am: 09.01.2010, 16:51    Titel: Antworten mit Zitat

mal so nebenbei... der pointer fängt immer mit ffff an. könnte das was bedeuten? grinsen

btw, ich mache ja keine vergleiche/zuweisungen, ich setz nen breakpoint und schaue mir dann die variable an Zunge rausstrecken
_________________
» Die Mathematik wurde geschaffen, um Probleme zu lösen, die es nicht gäbe, wenn die Mathematik nicht erschaffen worden wäre.
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden Website dieses Benutzers besuchen
28398



Anmeldungsdatum: 25.04.2008
Beiträge: 1917

BeitragVerfasst am: 09.01.2010, 18:28    Titel: Antworten mit Zitat

Der Pointer dürfte mit hoher Wahrscheinlichkeit nur dann mit 0xFFFF beginnen, wenn du das Programm in der IDE ausführst. VS dreht da irgendwas mit dem Speicher rum...
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
Beiträge der letzten Zeit anzeigen:   
Neues Thema eröffnen   Neue Antwort erstellen    Das deutsche QBasic- und FreeBASIC-Forum Foren-Übersicht -> Computer-Forum Alle Zeiten sind GMT + 1 Stunde
Seite 1 von 1

 
Gehe zu:  
Du kannst keine Beiträge in dieses Forum schreiben.
Du kannst auf Beiträge in diesem Forum nicht antworten.
Du kannst deine Beiträge in diesem Forum nicht bearbeiten.
Du kannst deine Beiträge in diesem Forum nicht löschen.
Du kannst an Umfragen in diesem Forum nicht mitmachen.

 Impressum :: Datenschutz