Pagina 1 di 2 1 2 ultimoultimo
Visualizzazione dei risultati da 1 a 10 su 12
  1. #1
    Utente di HTML.it
    Registrato dal
    Sep 2009
    Messaggi
    487

    [C++ (WIN 32)] Problema con GetAsyncKeyState in una procedura

    Ciao ragazzi, ho un problema:
    Se metto la funzione

    if(GetAsyncKeyState(VK_F2) < 0) MessageBox(NULL,"","",0);

    dentro una procedura per gestire una finestra e premo F2 non succede niente.
    O meglio per far comparire il MessageBox() devo premere più volte perchè all'interno della procedura non sente i tasti al primo colpo.

    Come posso fare?????

  2. #2
    Utente di HTML.it L'avatar di oregon
    Registrato dal
    Jul 2005
    residenza
    Roma
    Messaggi
    36,462
    Se non mostri il contesto in cui opera quella riga, non si potrà dire molto ...

    Serve il codice ...
    No MP tecnici (non rispondo nemmeno!), usa il forum.

  3. #3
    Utente di HTML.it
    Registrato dal
    Sep 2009
    Messaggi
    487

    Ecco il codice

    Ecco il codice, preso dagli esempi di dev-c++ e aggiunto solo la parte del MessageBox.

    Se lo eseguite e premete F2 e F3 quando la finestra è attiva, tutto ok.
    Ma se provate a premere i tasti finchè la finestra è per esempio ridotta ad icona e siete su un altro programma (es. dev-c++), per far comparire i MessageBox dovrete premere o tentere premuto i tasti più volte.

    Codice PHP:
    #include <windows.h>

    /*  Declare Windows procedure  */
    LRESULT CALLBACK WindowProcedure (HWNDUINTWPARAMLPARAM);

    /*  Make the class name into a global variable  */
    char szClassName[ ] = "WindowsApp";

    int IntPerNonFareComparireUnBordelloDiMessageBox 1;


    int WINAPI WinMain (HINSTANCE hThisInstance,
                        
    HINSTANCE hPrevInstance,
                        
    LPSTR lpszArgument,
                        
    int nFunsterStil)

    {
        
    HWND hwnd;               /* This is the handle for our window */
        
    MSG messages;            /* Here messages to the application are saved */
        
    WNDCLASSEX wincl;        /* Data structure for the windowclass */

        /* The Window structure */
        
    wincl.hInstance hThisInstance;
        
    wincl.lpszClassName szClassName;
        
    wincl.lpfnWndProc WindowProcedure;      /* This function is called by windows */
        
    wincl.style CS_DBLCLKS;                 /* Catch double-clicks */
        
    wincl.cbSize sizeof (WNDCLASSEX);

        
    /* Use default icon and mouse-pointer */
        
    wincl.hIcon LoadIcon (NULLIDI_APPLICATION);
        
    wincl.hIconSm LoadIcon (NULLIDI_APPLICATION);
        
    wincl.hCursor LoadCursor (NULLIDC_ARROW);
        
    wincl.lpszMenuName NULL;                 /* No menu */
        
    wincl.cbClsExtra 0;                      /* No extra bytes after the window class */
        
    wincl.cbWndExtra 0;                      /* structure or the window instance */
        /* Use Windows's default color as the background of the window */
        
    wincl.hbrBackground = (HBRUSHCOLOR_BACKGROUND;

        
    /* Register the window class, and if it fails quit the program */
        
    if (!RegisterClassEx (&wincl))
            return 
    0;

        
    /* The class is registered, let's create the program*/
        
    hwnd CreateWindowEx (
               
    0,                   /* Extended possibilites for variation */
               
    szClassName,         /* Classname */
               
    "Windows App",       /* Title Text */
               
    WS_OVERLAPPEDWINDOW/* default window */
               
    CW_USEDEFAULT,       /* Windows decides the position */
               
    CW_USEDEFAULT,       /* where the window ends up on the screen */
               
    544,                 /* The programs width */
               
    375,                 /* and height in pixels */
               
    HWND_DESKTOP,        /* The window is a child-window to desktop */
               
    NULL,                /* No menu */
               
    hThisInstance,       /* Program Instance handler */
               
    NULL                 /* No Window Creation data */
               
    );

        
    /* Make the window visible on the screen */
        
    ShowWindow (hwndnFunsterStil);

        
    /* Run the message loop. It will run until GetMessage() returns 0 */
        
    while (GetMessage (&messagesNULL00))
        {
            
    /* Translate virtual-key messages into character messages */
            
    TranslateMessage(&messages);
            
    /* Send message to WindowProcedure */
            
    DispatchMessage(&messages);
        }

        
    /* The program return-value is 0 - The value that PostQuitMessage() gave */
        
    return messages.wParam;
    }


    /*  This function is called by the Windows function DispatchMessage()  */

    LRESULT CALLBACK WindowProcedure (HWND hwndUINT messageWPARAM wParamLPARAM lParam)
    {
        
            
        if(
    GetAsyncKeyState(VK_F2) < && IntPerNonFareComparireUnBordelloDiMessageBox == 1
            {
            
    IntPerNonFareComparireUnBordelloDiMessageBox 0;
            
    MessageBox(NULL,"Il problema e' che non viene fuori sempre!\nInfatti bisogna premere F2 piu' di una volta!","Problema",MB_ICONERROR); 
            }   
            
        if(
    GetAsyncKeyState(VK_F3) < && IntPerNonFareComparireUnBordelloDiMessageBox == 0
            {
            
    IntPerNonFareComparireUnBordelloDiMessageBox 1;
            
    MessageBox(NULL,"Il problema e' che non viene fuori sempre!\nInfatti bisogna premere F3 piu' di una volta!","Problema",MB_ICONERROR);                                
            }
        
        
        
        switch (
    message)                  /* handle the messages */
        
    {
            case 
    WM_DESTROY:
                
    PostQuitMessage (0);       /* send a WM_QUIT to the message queue */
                
    break;
            default:                      
    /* for messages that we don't deal with */
                
    return DefWindowProc (hwndmessagewParamlParam);
        }

        return 
    0;


    PS eseiste un modo per evitare di fare tutto quel casino di
    "IntPerNonFareComparireUnBordelloDiMessageBox" ????

  4. #4

    Re: Ecco il codice

    Originariamente inviato da kirakira93
    Ecco il codice, preso dagli esempi di dev-c++ e aggiunto solo la parte del MessageBox.

    Se lo eseguite e premete F2 e F3 quando la finestra è attiva, tutto ok.
    Ma se provate a premere i tasti finchè la finestra è per esempio ridotta ad icona e siete su un altro programma (es. dev-c++), per far comparire i MessageBox dovrete premere o tentere premuto i tasti più volte.
    Questo perché la tua window procedure viene richiamata solo quando ci sono messaggi per la tua finestra. Quando la tua finestra è attiva arrivano molti messaggi (in particolare, quando premi un tasto, i vari WM_KEYDOWN/WM_KEYUP/...), per cui il controllo avviene di frequente e la message box appare subito; al contrario, quando la tua applicazione non è in primo piano le arrivano solo di tanto in tanto dei messaggi, e quindi solo in queste occasioni la tua window procedure viene eseguita.
    PS eseiste un modo per evitare di fare tutto quel casino di
    "IntPerNonFareComparireUnBordelloDiMessageBox" ????
    Questo dipende dal fatto che tu stai controllando se la GetAsyncKeyState restituisce un valore negativo, ossia che ha il bit più significativo attivo. Se controlli questo, di fatto vai a vedere se il tasto è premuto nel preciso istante in cui chiami GetAsyncKeyState. Per cui, se più messaggi arrivano uno dopo l'altro mentre è premuto il tasto, in tutte quelle occasioni GetAsyncKeyState ti dirà che il tasto è premuto, e verrà visualizzata la messagebox. Al contrario, tu devi verificare semplicemente se il tasto è stato premuto dall'ultima chiamata a GetAsyncKeyState, cosa che puoi fare controllando il bit meno significativo del valore restituito dalla funzione in questione, come spiegato nella documentazione.

    In ogni caso, stai usando gli strumenti sbagliati per il lavoro che intendi fare. Se vuoi controllare le pressioni di tasti mentre la tua finestra è attiva, lo strumento giusto è il semplice controllo dei messaggi WM_KEYDOWN all'interno della tua window procedure. Se invece vuoi controllare tutte le pressioni di tasti nel sistema, allora lo strumento giusto sono le hook globali, strumento comunque da utilizzare con cautela e parsimonia per motivi di prestazioni e per eventuali problemi che possono sorgere se la procedura di filtro ha dei bug.

    Colgo l'occasione per ribadire il consiglio che ti ho dato qualche tempo fa.
    Amaro C++, il gusto pieno dell'undefined behavior.

  5. #5
    Utente di HTML.it
    Registrato dal
    Sep 2009
    Messaggi
    487

    ok

    ok... MItaly hai ragione te..... adesso sono pienamente convinto: manuale in arrivo!
    Comunque, per GetAsyncKeyState ho risolto ponendo == -32767.
    In ogni caso, come potrei fare a richiamare una hook globale?

  6. #6
    Utente di HTML.it L'avatar di oregon
    Registrato dal
    Jul 2005
    residenza
    Roma
    Messaggi
    36,462

    Re: ok

    Originariamente inviato da kirakira93
    ...come potrei fare a richiamare una hook globale?
    Ma come ... prima dici che attendi un manuale e poi chiedi per l'hook globale (che è un argomento tra i più complessi per i programmatori esperti ...?)
    No MP tecnici (non rispondo nemmeno!), usa il forum.

  7. #7
    Utente di HTML.it
    Registrato dal
    Sep 2009
    Messaggi
    487

    ok

    ok lasciando perdere le hook, come potrei fare (utilizzando WM_KEYDOWN)

  8. #8

    Re: ok

    Originariamente inviato da kirakira93
    ok... MItaly hai ragione te..... adesso sono pienamente convinto: manuale in arrivo!
    Comunque, per GetAsyncKeyState ho risolto ponendo == -32767.
    Tecnicamente dovresti scrivere
    codice:
    if((GetAsyncKeyState(/*bla bla bla */) & 1)==1)
    Originariamente inviato da kirakira93
    ok lasciando perdere le hook, come potrei fare (utilizzando WM_KEYDOWN)
    Devi aggiungere allo switch della tua windows procedure un case per WM_KEYDOWN; per vedere come ottenere il tasto premuto, dai un'occhiata alla documentazione.
    Amaro C++, il gusto pieno dell'undefined behavior.

  9. #9
    Utente di HTML.it
    Registrato dal
    Sep 2009
    Messaggi
    487

    Grazie Mille, domani proverò il codice.

    Grazie Mille, domani proverò il codice.
    Comunque, ritornando alla questione del manuale 3 domande.
    1> Il maunale di win 32 che mi consigleresti in assouluto qual'è tra quelli che mi hai consigliato.
    2> Posso scaricare di quel manuale un e-book gratuito.
    3> Da che sito devo ordinarlo (se non è possibile avere l'ebook), magari anche da e-bay
    4> Ultima cosa --> Ma i manuali sono in inglese? Perchè in inglese me la cavo abbastanza bene, ma non ho mai provato a studiare in inglese (anche se penso che mi farebbe solo che bene )

  10. #10
    1) Io ho studiato sul Rector-Newcomer, ma ho sentito dire in giro che il Petzold è più completo; magari aspetta pareri di qualcun altro prima di comprare.
    2) No, sono entrambi libri normali protetti da copyright.
    3) Io andrei su Amazon.com, guardando magari nella sezione usati, tra cambio euro/dollaro e prezzo da usato finisce che spendi piuttosto poco. Tieni conto però che prima di qualche settimana non arriva se prendi la spedizione più economica, e se te lo bloccano in dogana potrebbe essere necessario inviare la documentazione in dogana (quando mi è capitato è bastato inviare una mail con un pdf del loro modulo compilato, più 5 € di spese non meglio precisate); altrimenti puoi andare di Amazon.co.uk (meno conveniente perché paghi in sterline, ma in UE, per cui arriva più in fretta e non hai problemi di dogana) o Play.com (che fa spedizione gratuita, ma ho visto che in generale non conviene rispetto ad Amazon).
    4) Sono in inglese (oddio, forse li hanno anche tradotti, ma non mi sono mai informato, preferisco leggerli in inglese), ma vai tranquillo, l'inglese tecnico è una passeggiata, e visto che praticamente tutta la documentazione è in inglese è un buon allenamento.
    Amaro C++, il gusto pieno dell'undefined behavior.

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2024 vBulletin Solutions, Inc. All rights reserved.