[Gelöst] MenuItemID von Menu mit Submenu ermitteln

Windowsspezifisches Forum , API ,..
Beiträge, die plattformübergreifend sind, gehören ins 'Allgemein'-Forum.
Benutzeravatar
N00B
Beiträge: 122
Registriert: 11.07.2007 22:28

Re: Menu mit Submenu über GetSubMenu ansprechen

Beitrag von N00B »

RSBasic hat geschrieben:Die MenuItem-Nummern sind immer statisch und es können maximal 65.536 verschiedene Menüeinträge erstellt werden.
Probiers einfach weiter, bis du den richtigen Wert gefunden hast.
Vielleicht schreibt jemand für dich ein Code, um die IDs aller Menüeinträge zu ermitteln, die vergeben sind.
Gute Nacht.
Es erstaunt mich immer wieder, was für Details fortgeschrittene und Profis kennen :) und vor allem, wie die die Winapi und diese verwirrenden Beschreibungen auf MSDN checken :)

Jedenfalls hab ich den benötigten Geistesblitz gekriegt mit dem Code den du geposted hast.

Danke RS :praise:
RSBasic

Code: Alles auswählen

  EnableExplicit

  Define handle
  
  ;RunProgram("notepad.exe")
  ;Delay(1000)
  handle = FindWindow_("Notepad2", #Null)
  If handle
    PostMessage_(handle, #WM_COMMAND, 40500, 0)
  Else
    Debug "Fenster konnte nicht gefunden werden."
  EndIf
  
Ich hab am Sonntag Morgen um 7 Uhr oder so, im PB 4.XX Code Archiv nenn Code gefunden gehabt.

http://www.purearea.net/pb/CodeArchiv/M ... em+Path.pb

Diesen musste ich nur leicht abändern damit er wieder funzt, und an der richtigen Stelle ein
GetMenuItemID_ hinzufügen, dann wurden mir diese 40xxx ID's (nennen wir sie mal Menu ID's) angezeigt.

Leider war ich nicht schlau genug das richtig zu interpretieren, ich war zu fixiert auf Menu Element Positionsangaben. (hätten die ein errechenbares logisches System gehabt, hätte ich oder der User, nicht eine "Menü Item ID unter Mauszeiger" Funktion benutzen müssen)

Hier ist der korrigierte und angepasste Code.

Code: Alles auswählen

  lpPoint.POINT
  #MN_GETHMENU = $1E1
  
  Global NewList lstSearchSubmenu.s()
  
  Structure Point64
    StructureUnion
    p.POINT
    q.q
    EndStructureUnion
  EndStructure
  
  Procedure SearchSubmenu(hMenu, hcurrmenu.l)
    count = GetMenuItemCount_(hMenu)
    For mnucount=0 To count -1
      hsubmenu = GetSubMenu_(hMenu, mnucount)
      If hsubmenu <> 0
        If hsubmenu = hcurrmenu.l
          mnuString.s = Space(255)
          GetMenuString_(hMenu, mnucount, @mnuString, Len(mnuString), #MF_BYPOSITION)
          InsertElement(lstSearchSubmenu.s())
          lstSearchSubmenu.s() = mnuString
          ProcedureReturn #True
        Else
          erg = SearchSubmenu(hsubmenu, hcurrmenu.l)
          If erg = #True
            mnuString.s = Space(255)
            GetMenuString_(hMenu, mnucount, @mnuString, Len(mnuString), #MF_BYPOSITION)
            InsertElement(lstSearchSubmenu.s())
            lstSearchSubmenu.s() = mnuString
            ProcedureReturn erg
          EndIf
        EndIf
      EndIf
    Next
  EndProcedure
  
  While 1=1
    GetCursorPos_(cursor.Point64)
    hwnd = WindowFromPoint_(cursor\q)
    Submenucount = 0
    phwnd = GetParent_(hwnd)  ;Fenster-Handle
    hMenu = GetMenu_(phwnd)
    hcurrmenu.l = SendMessage_(hwnd, #MN_GETHMENU, 0,0)
    menuPos = MenuItemFromPoint_(hwnd, hcurrmenu.l,cursor\q)
    If oldmenuPos <> menuPos
      SearchSubmenu(hMenu, hcurrmenu.l)
      mnuString.s = Space(255)
      Debug GetMenuItemID_(hcurrmenu,menuPos) 
      GetMenuString_(hcurrmenu.l, menuPos, @mnuString, Len(mnuString), #MF_BYPOSITION)
      LastElement(lstSearchSubmenu.s())
      AddElement(lstSearchSubmenu.s())
      lstSearchSubmenu.s() = mnuString
      Debug "------------" 
      ForEach lstSearchSubmenu.s()
        Debug lstSearchSubmenu.s()
      Next
      ClearList(lstSearchSubmenu.s())
      oldmenuPos = menuPos
    EndIf
    Submenucount = 0
  Wend 
  
  
  
  ; IDE Options = PureBasic v4.02 (Windows - x86)
  ; Folding = -

Ich hab mir draus nenn kleinen Code Fetzen gebastelt (ich mag kleine Codes, sind vertändlicher) der das selbe tut (jeder Name und jede ID eine Menü Elementes wird ausgegeben) einziger Unterschied, mein Code zeigt im "File"->"Launch" Menü von Notepad2 folgendes an

Code: Alles auswählen

0
&New Window	Alt+N
40011
-------------
der große Code oben das hier.

Code: Alles auswählen

8
------------
&File
&Launch
-1
-1
------------
&File
&Launch

40011
0
------------
&File
&Launch
&New Window	Alt+N
-1
-1
------------
Postmessage und Sendmessage funzen.

Code: Alles auswählen

SendMessage_(handle,#WM_COMMAND,menu_item_id,handle)
; Das Handle hinten ist wurscht, kann mann auch ne null reinsetzen und es geht, nur das ;Fenster/Menu Handle vorne zählt, und die richtige menu_item_id
und mit Postmessage (wie du es vorgeschlagen hast :allright: ) ist es das selbe, nur ohne die komische Handle angabe hinten.

Code: Alles auswählen

PostMessage_(handle, #WM_COMMAND,menu_item_id, 0)

3Hier mein kleinerer Code

Code: Alles auswählen

  
  Structure Point64
    StructureUnion
    p.POINT
    q.q
    EndStructureUnion
  EndStructure
  
  Repeat
    GetCursorPos_(cursor.Point64)  
    hwnd = WindowFromPoint_( cursor\q ) 
    phwnd = GetParent_(hwnd)  ;Fenster-Handle
    hMenu = GetMenu_(phwnd)
    hcurrmenu.l = SendMessage_(hwnd, #MN_GETHMENU, 0,0)
    menuPos = MenuItemFromPoint_(hwnd, hcurrmenu.l,cursor\q)
    If menuPos <> oldmenuPos
      menu_id = GetMenuItemID_(hcurrmenu,menuPos)
      mnuString.s = Space(255) 
      GetMenuString_(hcurrmenu.l, menuPos, @mnuString, Len(mnuString), #MF_BYPOSITION)
      If menu_id <> -1
        Debug menuPos
        Debug mnuString
        Debug menu_id
        Debug "-------------"
      EndIf
      oldmenuPos = menuPos 
    EndIf 
    Delay(100) 
  ForEver 
Soweit funzt alles, jedoch hab ich jetzt ein anderes Problem, kein Code den ich versucht habe,
schafft es bei gewissen Fenstern (AMD Power Monitor, Firefox, Seamonkey) das ich trotz richtigem Fenster Handle

(weiß ich weil SetForegroundWindow funzt, aber nur wenn die Anwendung nicht minimiert wurde, wurde sie minimiert muss ich erst ShowWindow_(handle,#SW_SHOW) benutzen) weil sonst ein falsches Handle ermittelt wird, in meinem Fall 48301700 statt 13370340)

hier bei diesen 2 Befehlen

GetParent_
GetMenu_

nicht eine 0 als Rückgabewert kriege, GetMenu_ braucht den Wert von GetParent, GetParent wiederum, gibt nur ne 0 aus.

Die Codes funzen einwandfrei, bei anderen Anwendungen (Notepad2, Notepad, Total Commander usw)

Was auch sehr merkwürdig ist, ich hab hier im Board nenn Code gefunden, der mir die Elemente von nem Fenster anzeigt, so in der Art.

Beispiel Notepad2

Code: Alles auswählen

[Title]=  [hWnd]= 7996014 [ClassName]= Scintilla
[Title]=  [hWnd]= 8978876 [ClassName]= SysListView32
[Title]=  [hWnd]= 6620154 [ClassName]= msctls_statusbar32
[Title]=  [hWnd]= 9634652 [ClassName]= ReBarWindow32
[Title]=  [hWnd]= 29229440 [ClassName]= ToolbarWindow32
[Title]=  [hWnd]= 21627878 [ClassName]= Static
[Title]= 508550937 [hWnd]= 90112862 [ClassName]= Static
7 <-- Anzahl der Elemente
Nehme ich eine Anwendung wie Seamonkey,Firefox oder den AMD Powermonitor
kriege ich nur "0" vom Debugger geliefert, sonst gar nichts, auch wenn ich ein Class Element (weiß nicht genau was ne Class ist) wie "MozillaWindowClass" benutze.

Code: Alles auswählen

Procedure EnumChildProc(hwnd.l, *lParam.Long)
  Protected title.s{1024}
  Protected class.s{1024}
  Debug hwnd
  *lParam\l + 1
  GetWindowText_(hwnd,@title,1024) ;Fenstertitel auslesen
  GetClassName_(hwnd,@class,1024)  ;Fensterklasse auslesen
  Debug "[Title]= " + title + " [hWnd]= " + Str(hwnd) + " [ClassName]= " + class;Werte ausgeben
  ProcedureReturn #True
EndProcedure
  
Procedure EnumChildWindows(hwnd.l, WindowTitel.s = "")
  If WindowTitel <> ""
    hwnd = FindWindow_(0, @WindowTitel)
  EndIf
  If hwnd = 0
    ProcedureReturn 0
  EndIf
  Protected Anzahl.l
  EnumChildWindows_(hwnd, @EnumChildProc(), @Anzahl)
  ProcedureReturn Anzahl
EndProcedure
  
MainWin$ = "SeaMonkey"
Debug EnumChildWindows(0,MainWin$) ; Debug zeigt an wieviele Elemente es gibt
Hier der Code den ich nicht verändert hab (hab nur Kommentare reingesetzt) den ich benutze um

Titel,Klasse & PID zu erhalten.

Code: Alles auswählen

  Procedure EnumWindows(hwnd,ignore) ;Prozedur, die die Handles der Fenster erhält
    
    Mode = 0
    
    ;0 Show Visible Only
    ;1 Show All
    ;2 Show Invisible Only
    
    If IsWindowVisible_(hwnd)
      If Mode <= 1
        ShowWin=1 
      EndIf 
    Else
      If Mode >= 1
        ShowWin=1 
      EndIf 
    EndIf
    
    If ShowWin
      
      title.s=Space(1024) : class.s=Space(1024) : pid.l=0
      GetWindowText_(hwnd,@title,1024) ;Fenstertitel auslesen
      GetClassName_(hwnd,@class,1024)  ;Fensterklasse auslesen
      GetWindowThreadProcessId_(hwnd,@pid) ;PID des zugehörigen Prozesses auslesen
      Debug "[Title]= "+title+" [hWnd]= "+Str(hwnd)+" [ClassName]= "+class+" [PID]= "+Str(pid) ;Werte ausgeben
      
    EndIf
    
    ProcedureReturn #True ;#True wird von der WinAPI als Rückgabewert benötigt
  EndProcedure
  
  EnumWindows_(@EnumWindows(),0) ;API, die die Handles von allen Fenstern an die Funktion EnumWindows() übergibt
Alle Codes funzen, nur Firefox,Seamonkey & der AMD Power Monitor, machen zicken :freak:
Benutzeravatar
edel
Beiträge: 3667
Registriert: 28.07.2005 12:39
Computerausstattung: GameBoy
Kontaktdaten:

Re: Teilweise gelöst-Menu mit Submenu über GetSubMenu anspre

Beitrag von edel »

Firefox und ich glaube auch Seamonkey benutzen Gecko bzw XUL um die Fenster darzustellen. Es ist also nichts anderes als eine Webseite die eine Webseite darstellen kann. Das Toolkit QT benutzt z. B. auch keine WinAPI. Falls dein "AMD Power Monitor" auch so etwas benutzt, kommst du mit der WinAPI nicht sehr weit.
SendMessage_(handle,#WM_COMMAND,menu_item_id,handle)
; Das Handle hinten ist wurscht, kann mann auch ne null reinsetzen und es geht, nur das ;Fenster/Menu Handle vorne zählt, und die richtige menu_item_id
Das ist nicht "Wurscht". Auf MSDN gibt es eine Tabelle, die das genau beschreibt was man fuer welches "Kommando" angeben muss. In deinem Fall muss dort also eine 0 stehen.

Auf catch22 findest du ein sehr gutes Programm, um in fremden Fenstern herumzuschnueffeln.
Benutzeravatar
N00B
Beiträge: 122
Registriert: 11.07.2007 22:28

Re: Teilweise gelöst-Menu mit Submenu über GetSubMenu anspre

Beitrag von N00B »

edel hat geschrieben:Firefox und ich glaube auch Seamonkey benutzen Gecko bzw XUL um die Fenster darzustellen. Es ist also nichts anderes als eine Webseite die eine Webseite darstellen kann. Das Toolkit QT benutzt z. B. auch keine WinAPI. Falls dein "AMD Power Monitor" auch so etwas benutzt, kommst du mit der WinAPI nicht sehr weit.
SendMessage_(handle,#WM_COMMAND,menu_item_id,handle)
; Das Handle hinten ist wurscht, kann mann auch ne null reinsetzen und es geht, nur das ;Fenster/Menu Handle vorne zählt, und die richtige menu_item_id
Das ist nicht "Wurscht". Auf MSDN gibt es eine Tabelle, die das genau beschreibt was man fuer welches "Kommando" angeben muss. In deinem Fall muss dort also eine 0 stehen.

Auf catch22 findest du ein sehr gutes Programm, um in fremden Fenstern herumzuschnueffeln.
Also ist es doch Wurscht :D denn für meinen Fall, kann ich da jeglichen Humbug angeben.
hab -1 bis 5 probiert, und es geht immer !

Code: Alles auswählen

  handle=16843164
  
  main_menu_handle = GetMenu_(handle)
  Debug "Menu Handle="+Str(main_menu_handle) 
  menu_id = GetSubMenu_(main_menu_handle,2) ;0 = First Menu from Left Site
  Debug "Menu ID="+Str(menu_id)  
  max_items=GetMenuItemCount_(menu_id)
  Debug "Menu Items="+Str(max_items)  
  mnuString.s = Space(255)
  LenOfMnuString = GetMenuString_(main_menu_handle,0, @mnuString, Len(mnuString),#MF_BYPOSITION)
  Debug "==="+Str(LenOfMnuString-1)
  Debug "======"+mnuString  
  menu_item_id = 40011 ; File->Launch->New Window unter Notepad2
  SendMessage_(handle,#WM_COMMAND,menu_item_id,-1) ; <--- das Handle hinten ist wurscht !
Wenn ich das auf MSDN richtig verstanden habe, wird bei Menu oder Accelerator eine 0
verwendet, und die Control Teile, brauchen ein Handle, und das hat mindestens 5 stellen, da der Code von mir immer funzt, egal ob hinten -1 oder z.B 3 geh ich von aus, daß SendMessage automatisch 0 benutzt.

Weil wenn #WM_COMMAND benutzt wird und der Wert hinten kleiner als eine 5 stellige Zahl ist (hab noch kein Handle gesehen das weniger als 5 Stellen benutzt) dann bleibt ja nur noch die Möglichkeit, daß es sich um Menu oder Accelerator handelt.

Was HiWord, LoWord ist (ein Variablen Typ vielleicht ?) weiß ich nicht, aber hab ich in 6 Jahren noch nie gebraucht, also wird es für mich persöhnlich nicht wichtig sein.

Danke für den Tip mit WinSpy++ echt geil das Teil :allright:
benutze aber in meinem Tool, nenn Code, der mir das Handle von nem Fenster unter dem Zeiger ausgibt, und die Menu Item ID :) aber werde das Spy++ trotzdem aufheben, ist echt cool :)
Benutzeravatar
edel
Beiträge: 3667
Registriert: 28.07.2005 12:39
Computerausstattung: GameBoy
Kontaktdaten:

Re: Teilweise gelöst-Menu mit Submenu über GetSubMenu anspre

Beitrag von edel »

Sendmessage uebergibt das was du dort auch schreibst, alles weitere liegt an dem Programm.

Code: Alles auswählen

Macro LOWORD(a)      : ( a & $ffff)                          : EndMacro
Macro HIWORD(a)      : (a >> 16)                             : EndMacro
Macro MAKEWPARAM(l,h): (((h) & $FFFF) << 16 | ((l) & $FFFF)) : EndMacro

Procedure SendMessage(hwnd, msg, wparam, lparam)
  
  If Not lparam = 0
    Debug "Control"
  ElseIf HIWORD(wparam) = 1
    Debug "Hotkey"
  ElseIf HIWORD(wparam) = 0
    Debug "Menu"
  EndIf

EndProcedure


wparam = MAKEWPARAM(0,0)
lparam = 0

SendMessage(0, 0, wparam, lparam)

wparam = MAKEWPARAM(0,0)
lparam = -1

SendMessage(0, 0, wparam, lparam)

Benutzeravatar
N00B
Beiträge: 122
Registriert: 11.07.2007 22:28

Re: Teilweise gelöst-Menu mit Submenu über GetSubMenu anspre

Beitrag von N00B »

edel hat geschrieben:Sendmessage uebergibt das was du dort auch schreibst, alles weitere liegt an dem Programm.

Code: Alles auswählen

Macro LOWORD(a)      : ( a & $ffff)                          : EndMacro
Macro HIWORD(a)      : (a >> 16)                             : EndMacro
Macro MAKEWPARAM(l,h): (((h) & $FFFF) << 16 | ((l) & $FFFF)) : EndMacro

Procedure SendMessage(hwnd, msg, wparam, lparam)
  
  If Not lparam = 0
    Debug "Control"
  ElseIf HIWORD(wparam) = 1
    Debug "Hotkey"
  ElseIf HIWORD(wparam) = 0
    Debug "Menu"
  EndIf

EndProcedure


wparam = MAKEWPARAM(0,0)
lparam = 0

SendMessage(0, 0, wparam, lparam)

wparam = MAKEWPARAM(0,0)
lparam = -1

SendMessage(0, 0, wparam, lparam)

So oder so, es kommt immer das selbe Ergebnis aus.

Code: Alles auswählen

 Macro LOWORD(a)      : ( a & $FFFF)                          : EndMacro
  Macro HIWORD(a)      : (a >> 16)                             : EndMacro
  Macro MAKEWPARAM(l,h): (((h) & $FFFF) << 16 | ((l) & $FFFF)) : EndMacro
  
  Procedure SendMessage(hwnd, msg, wparam, lparam)
    
    If Not lparam = 0
      Debug "Control"
    ElseIf HIWORD(wparam) = 1
      Debug "Hotkey"
    ElseIf HIWORD(wparam) = 0
      Debug "Menu"
    EndIf
    
    SendMessage_(hwnd,#WM_COMMAND,wparam,lparam)
    
  EndProcedure
  
  
  handle = 16843164
  
  wparam = MAKEWPARAM(0,0)
  lparam = 0
  
  ;SendMessage(handle, 0, wparam, lparam)
  
  wparam = MAKEWPARAM(0,0)
  lparam = -1
  
  SendMessage(handle,#WM_COMMAND,40011,0)
Und Notepad2 macht genau das was es soll, "File"->"Launch"->"New Window" aufrufen.

WM_Command reinsetzen, Menü ID, und selbst wenn ich bei lparam 4000 reinmache, funzt es.

Ausserdem woher willst du Wissen, ob nicht das API Command >intern< so arbeitet

Abchecken ob WM_Command, wenn ja und lparam keinem Handle entspricht b.z.w kleiner als einer Handle Länge überhaupt sein kann (Handle Werte unterhalb von 5 stellen konnte ich nirgends finden) dann automatisch lparam als 0 interpretieren, egal was gesendet wurde.

Irgendeine Art der Korrektur muss ja stattfinden, sonst würde es nicht gehen.
Benutzeravatar
edel
Beiträge: 3667
Registriert: 28.07.2005 12:39
Computerausstattung: GameBoy
Kontaktdaten:

Re: Teilweise gelöst-Menu mit Submenu über GetSubMenu anspre

Beitrag von edel »

Du kennst den Quellcode doch gar nicht. Mein obiger Code sollte dir zeigen, wie die Programme auf eine Nachricht regieren bzw wie sie verarbeitet werden könnte. Hältst du dich nicht an die Regeln, kann es schief gehen. Aber am Ende ist es mir egal, welche Parameter du wo übergibst, es sollte nur ein Hinweis sein.
Benutzeravatar
NicTheQuick
Ein Admin
Beiträge: 8809
Registriert: 29.08.2004 20:20
Computerausstattung: Ryzen 7 5800X, 64 GB DDR4-3200
Ubuntu 24.04.2 LTS
GeForce RTX 3080 Ti
Wohnort: Saarbrücken

Re: Teilweise gelöst-Menu mit Submenu über GetSubMenu anspre

Beitrag von NicTheQuick »

Da findet keine Korrektor statt. Es wird einfach nur jeder Parameter genau so an den WindowCallback übergeben wie du es sendest. 'SendMessage_()' weiß ja nicht, was in dem WindowCallback gemacht wird, an den es sendet. Warum sollte es dann irgendwas korrigieren? Dann hätte man ja auch noch eine Einschränkung für eigene WindowCallbacks, was keinen Sinn macht.
Benutzeravatar
N00B
Beiträge: 122
Registriert: 11.07.2007 22:28

Re: Teilweise gelöst-Menu mit Submenu über GetSubMenu anspre

Beitrag von N00B »

Wie mein Name schon aussagt, ich bin ein Noob :bounce: und ihr werdet schon Recht haben :allright:

Viel wichtiger ist, ich bin heute zum 2. mal Onkel geworden :bounce:

Meine Schwester, die seit 3 Monaten in Griechenland im KHaus liegt, wegen Frühgeburt Gefahr, hat heute an ihrem Geburtstag, in der 39.Woche ihre Kleine auf die Welt gebracht. :allright:

Hier die Lösung b.z.w der Code für mein Problem aus'm ersten Post.

Code: Alles auswählen

Structure Point64
    StructureUnion
    p.POINT
    q.q
    EndStructureUnion
  EndStructure
 
  Repeat
    GetCursorPos_(cursor.Point64) 
    hwnd = WindowFromPoint_( cursor\q )
    phwnd = GetParent_(hwnd)  ;Fenster-Handle
    hMenu = GetMenu_(phwnd)
    hcurrmenu.l = SendMessage_(hwnd, #MN_GETHMENU, 0,0)
    menuPos = MenuItemFromPoint_(hwnd, hcurrmenu.l,cursor\q)
    If menuPos <> oldmenuPos
      menu_id = GetMenuItemID_(hcurrmenu,menuPos)
      mnuString.s = Space(255)
      GetMenuString_(hcurrmenu.l, menuPos, @mnuString, Len(mnuString), #MF_BYPOSITION)
      If menu_id <> -1
        Debug menuPos
        Debug mnuString
        Debug menu_id
        Debug "-------------"
      EndIf
      oldmenuPos = menuPos
    EndIf
    Delay(100)
  ForEver 
ja ich weiss, ohne Enable Explicit usw aber das ist mir jetzt Schnuppe, wer den Code verwenden will, kann den ja entsprechend abändern.

Danke noch mal an all die Tips. :allright:
Benutzeravatar
RSBasic
Admin
Beiträge: 8047
Registriert: 05.10.2006 18:55
Wohnort: Gernsbach
Kontaktdaten:

Re: [Gelöst] MenuItemID von Menu mit Submenu ermitteln

Beitrag von RSBasic »

Herzlichen Glückwunsch, freut mich sehr, dass du zum zweiten Mal Onkel geworden bist. :allright:

Hier dein Code in enableexpliciter Form:

Code: Alles auswählen

EnableExplicit

Structure Point64
  StructureUnion
    p.POINT
    q.q
  EndStructureUnion
EndStructure

Define cursor.Point64
Define hwnd
Define phwnd
Define hMenu
Define hcurrmenu.l
Define menuPos
Define oldmenuPos
Define menu_id
Define mnuString.s

Repeat
  GetCursorPos_(cursor)
  hwnd = WindowFromPoint_( cursor\q )
  phwnd = GetParent_(hwnd)  ;Fenster-Handle
  hMenu = GetMenu_(phwnd)
  hcurrmenu = SendMessage_(hwnd, #MN_GETHMENU, 0,0)
  menuPos = MenuItemFromPoint_(hwnd, hcurrmenu.l,cursor\q)
  If menuPos <> oldmenuPos
    menu_id = GetMenuItemID_(hcurrmenu,menuPos)
    mnuString.s = Space(255)
    GetMenuString_(hcurrmenu.l, menuPos, @mnuString, Len(mnuString), #MF_BYPOSITION)
    If menu_id <> -1
      Debug menuPos
      Debug mnuString
      Debug menu_id
      Debug "-------------"
    EndIf
    oldmenuPos = menuPos
  EndIf
  Delay(100)
ForEver 
Man kann es auch in einer Prozedur oder in einem Thread einfügen.
Aus privaten Gründen habe ich leider nicht mehr so viel Zeit wie früher. Bitte habt Verständnis dafür.
Bild
Bild
Benutzeravatar
N00B
Beiträge: 122
Registriert: 11.07.2007 22:28

Re: [Gelöst] MenuItemID von Menu mit Submenu ermitteln

Beitrag von N00B »

RSBasic hat geschrieben:Herzlichen Glückwunsch, freut mich sehr, dass du zum zweiten Mal Onkel geworden bist. :allright:

Hier dein Code in enableexpliciter Form:

Code: Alles auswählen

EnableExplicit

Structure Point64
  StructureUnion
    p.POINT
    q.q
  EndStructureUnion
EndStructure

Define cursor.Point64
Define hwnd
Define phwnd
Define hMenu
Define hcurrmenu.l
Define menuPos
Define oldmenuPos
Define menu_id
Define mnuString.s

Repeat
  GetCursorPos_(cursor)
  hwnd = WindowFromPoint_( cursor\q )
  phwnd = GetParent_(hwnd)  ;Fenster-Handle
  hMenu = GetMenu_(phwnd)
  hcurrmenu = SendMessage_(hwnd, #MN_GETHMENU, 0,0)
  menuPos = MenuItemFromPoint_(hwnd, hcurrmenu.l,cursor\q)
  If menuPos <> oldmenuPos
    menu_id = GetMenuItemID_(hcurrmenu,menuPos)
    mnuString.s = Space(255)
    GetMenuString_(hcurrmenu.l, menuPos, @mnuString, Len(mnuString), #MF_BYPOSITION)
    If menu_id <> -1
      Debug menuPos
      Debug mnuString
      Debug menu_id
      Debug "-------------"
    EndIf
    oldmenuPos = menuPos
  EndIf
  Delay(100)
ForEver 
Man kann es auch in einer Prozedur oder in einem Thread einfügen.
Danke RSBasic :) yop, nichts anderes habe ich auch in meinem kleinen Tool gemacht :) jedoch benutze ich eigentlich nie enable explicit (das Gemecker wenn mann dann fremde Codes Compilen
will, die das aktiviert haben, abzuändern, nervt mich :D) vermeide globale Variablen (macros erst Recht) benutze wo es geht Prozeduren, variablen ausserhalb der Prozeduren vermeidet ich auch, und ich habs mir angewöhnt in Prozeduren wenn möglich sowas als variablen namen zu benutzen

tmp_str1$
tmp_str2$
tmp_val1
tmp_val2
tmp_p1
tmp_p2
tmp_max1
tmp_max2
tmp_s1
tmp_s2
tmp_c1
tmp_c2

bei temporären Werten.

s für state, val für wert, c für count, p für position, max für maximalen Wert, fahre damit eigentlich ganz gut seit paar Jahren :)

In manchen Dingen allerdings, bin ich nach Jahren immer noch der volle Noob :D ich blick von vielen Dingen nicht den Sinn (maps z.B vieles erschliesst sich erst in der Anwendung, wenn benötigt) oder hab erst nach 2 Jahren gecheckt, daß mann Structuren auch ohne LinkedLists benutzen kann (hab das erste mal Strukturen in der LinkedLists Anleitung gesehen, copy & paste und direkt rumexperimentiert, ohne großartig zu lesen)

Wie auch immer.

Du hast ja diese Coole WinAPI Library, und das coole Tool dazu (ne Wort Such Funktion dann währe es perfekt) kannst ja den Code reinstellen.,
Antworten