Newsgroup: it.comp.programmare.win32
Titolo: Rilevare il click su un menu?

Salve,
Finalmente sono riuscito a creare( grazie al determinante aiuto di Stefano )
una
finestra e diversi controlli, piu' il menu.
Ho scoperto che per reagire al menu bisogna intercettare il messaggio
WM_COMMAND,
anche se sinceramente non ho capito come distinguere un elemento del menu da
un altro.
Qualcuno ha idee su come risolvere il problema?
Andrea

The DeerBear wrote:
<snip>
Leggendo MSDN, in teoria, se io specifico in InsertMenu "MF_BYPOSITION" il
messaggio spedito dovrebbe essere "WM_MENUCOMMAND" ma in realta'
cosě non e', in quanto viene spedito un banalissimo WM_COMMAND.
Che devo fare?
Andrea

 cosě non e', in quanto viene spedito un banalissimo WM_COMMAND.
eh? in MSDN c'č scritto cosě? da quanto mi risulta il messaggio
WM_MENUCOMMAND non esiste...
cmq per distinguere un menu item da un altro, vedi il WORD inferiore del
parametro wParam che ti viene passato nella WindowProc (in altre parole:
LOWORD(wParam))
-- 
questo articolo e` stato inviato via web dal servizio gratuito 
http://www.newsland.it/news
 segnala gli abusi ad 
ab...@newsland.it


1. MSDN
2. un buon libro
3. google
Io ti consiglio la 2. Federico.

 Io ti consiglio la 2. Federico.
io avrei detto la prima: è più che sufficiente, senza andare a perdere
tempo a cercare con Google.


 parole: LOWORD(wParam))
Eh, questo in teoria... ma come al solito la teoria differisce dalla
pratica.
Avevo gia' letto su MSDN questo dettaglio ma naturalmente, per qualche
ragione a me sconosciuta, la cosa non funziona.
Almeno, non funziona a me.
Questo è ( semplificato ) il codice che uso:
function WndProc( hwnd : HWND;mesg : UINT;wparam : WPARAM;lparam : LPARAM )
: LongInt;stdcall;
var FuncR : LongInt;
//    GDC : HDC;
//    Rect : TRect;
    TstNum,
    TstNum2 : PChar;
begin
  FuncR := -1;
  case mesg of
    WM_CREATE : begin
                  FuncR := 0;
                end;
    WM_DESTROY : begin
                   PostQuitMessage( 0 );
                   FuncR := 0;
                 end;
    {WM_LBUTTONDOWN : begin
                      MessageBox( hwnd,'Mouse down','Application',MB_OK );
                    end;}
    WM_COMMAND : begin
                   if hwnd = BtnWnd then
                     MessageBox( hwnd,'Button click','Application',MB_OK );
                   if HiWord( WParam ) = 0 then
                   begin
                     GetMem( TstNum,255 );
                     TstNum2 := StrPCopy( TstNum, IntToStr( LoWord(
WParam ) ) );
                     MessageBox( hwnd,TstNum2,'WParam',MB_OK );
                     FreeMem( TstNum );
                     GetMem( TstNum,255 );
                     StrPCopy( TstNum, IntToStr( MENU_ITEM ) );
                     MessageBox( hwnd,TstNum,'Application',MB_OK );
                     FreeMem( TstNum );
                     GetMem( TstNum,255 );
                     StrPCopy( TstNum, IntToStr( LParam ) );
                     MessageBox( hwnd,TstNum,'Application',MB_OK );
                     FreeMem( TstNum );
                   end;
                 end;
    {WM_PAINT : begin
                 if GetUpdateRect( MainWnd,Rect,True ) then
                 begin
                   GDC := CreateCompatibleDC( GetDC( MainWnd ) );
                 end;
               end;}
    WM_MENUCOMMAND : begin
                       GetMem( TstNum,255 );
                       StrPCopy( TstNum, IntToStr( LoWord( WParam ) ) );
                       MessageBox( hwnd,TstNum,'WParam',MB_OK );
                       FreeMem( TstNum );
                     end;
  else
    FuncR := DefWindowProc( hwnd,mesg,wparam,lparam );
  end;
  Result := FuncR;
end;
Le parentesi graffe sono commenti nel caso specifico.
Questo è il "pezzo" di interesse:
WM_COMMAND : begin
                   if hwnd = BtnWnd then
                     MessageBox( hwnd,'Button click','Application',MB_OK );
                   if HiWord( WParam ) = 0 then
                   begin
                     GetMem( TstNum,255 );
                     TstNum2 := StrPCopy( TstNum, IntToStr( LoWord(
WParam ) ) );
                     MessageBox( hwnd,TstNum2,'WParam',MB_OK );
                     FreeMem( TstNum );
                     GetMem( TstNum,255 );
                     StrPCopy( TstNum, IntToStr( MENU_ITEM ) );
                     MessageBox( hwnd,TstNum,'Application',MB_OK );
                     FreeMem( TstNum );
                     GetMem( TstNum,255 );
                     StrPCopy( TstNum, IntToStr( LParam ) );
                     MessageBox( hwnd,TstNum,'Application',MB_OK );
                     FreeMem( TstNum );
                   end;
                 end;
Come vedete, si richiama HiWord per vedere se è un menu, e poi si vorrebbe
visualizzare il risultato di LoWord per verificare che effettivamente sia
quello
interessato. Sfortunatamente - invece - esce sempre ZERO, anche quando
l'identificativo del menu dovrebbe portare ad un risultato diverso.
Ecco il codice con cui viene creato il menu:
const MENU_ITEM = WM_USER+100;
...
MenuWnd := CreateMenu;
  InsertMenu( MenuWnd,MENU_ITEM,MF_BYCOMMAND or MF_ENABLED or
MF_STRING,0,'Test ITEM' );
  SetMenu( MainWnd,MenuWnd );
MENU_ITEM ha un valore abbastanza alto, tuttavia il WParam non sembra
accorgersene.
Idee?
Andrea

MF_STRING,0,'Test ITEM' );
MenuWnd := CreateMenu;
  InsertMenu( MenuWnd,-1,MF_BYPOSITION or MF_ENABLED or
MF_STRING,MENU_ITEM,'Test ITEM' );
BOOL InsertMenu(
    HMENU hMenu,
    UINT uPosition,
    UINT uFlags,
    PTR uIDNewItem,
    LPCTSTR lpNewItem
);
   Tu metti MENU_ITEM in uPosition, che serve a indicare la posizione
del nuovo elemento, precisamente dopo quale elemento esistente
inserirlo (come l'ho messo io, indica di inserirlo alla fine). Devi
inserire l'ID del nuovo elemento in uIDNewItem.
-- 
S.L.