[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

[Gelöst] MenuItemID von Menu mit Submenu ermitteln

Beitrag von N00B »

Hi

Ich hab hier Problem, ich hoffe ihr könnt mir helfen.

Google und probiere schon locker seit ca 15 Stunden rum, hab kein Nerv
mehr -.-

Also der Code sendet ein Klick zu nem Menu von nem anderen Prog (komischerweise geht der
bei keinem einzigen Prog das in PB geschrieben wurde, sende ich an Tools wie paint,notepad,notepad2 die nicht in pb geschrieben wurden funzt es wenigstens wenn kein Untermenü Eintrag angeklickt werden soll)

getestet hab ich es mit notepad,paint & notepad2

Das Problem ist, daß ich es einfach nicht hinkriege, einen Eintrag von einem Untermenü
anzusprechen.

z.B

Code: Alles auswählen

File
-------
New
Open
Save
Save as -> as bla1
           as bla2
           as bla3
Close
Exit
Für alles unter dem "Save as" Untermenü krieg ich keine gültige ID, und egal
was ich an Werten probiert hab, es funzt einfach nicht.

Alles andere, daß nicht in einem Untermenü ist, wird ausgeführt.


Benutze StickyWindow und ein F5 Keyevent, damit ich schnell das Window Handle
vom Fenster über das die Maus grade ist, kriege.

Einfach mal mit Paint testen, funzt (Toolbox wird ausgeblendet/eingeblendet, wenn Window Handle von Paint benutzt wird) soweit, bis auf "Ansicht"->"Zoom"->alle Einträge unter Zoom

Code: Alles auswählen

  Enumeration
    #MainWin
    #Bla_T
    #DAMN_WORK_NOW
  EndEnumeration 
  
  Global Pause
  
  Structure Point64
    StructureUnion
    p.POINT
    q.q
    EndStructureUnion
  EndStructure
  
  Procedure ShowHandle(nevermind)
    hndl = 0
    cursor.Point64 
    Repeat
      GetCursorPos_(cursor.Point64)  
      hndl = WindowFromPoint_( cursor\q )
      If Pause = 0
        SetGadgetText(#Bla_T,"Handle-ID: "+Str(hndl))
      Else
        SetGadgetText(#Bla_T,GetGadgetText(#Bla_T)+" FREEZED") 
        SetClipboardText(Str(hndl))
        Debug "WINDOW HANDLE="+GetClipboardText()
        beep_(600,100)
        Repeat
          Delay(2)
        Until Pause=0
      EndIf
      Delay(100)
    ForEver
    
  EndProcedure
  
  Procedure ClearKeyBuffers(nevermind)
    
    Repeat
      If GetActiveWindow() <> #MainWin
        nothing=GetAsyncKeyState_(#VK_F5)
      EndIf
      Delay(2)
    ForEver 
    
  EndProcedure
  
  If OpenWindow(#MainWin,0,0,200,300,"Send from me",#PB_Window_SystemMenu|#PB_Window_MinimizeGadget|#PB_Window_ScreenCentered)
    StickyWindow(#MainWin,1) 
    
    TextGadget(#Bla_T,10,100,200,20,"")
    
    ButtonGadget(#DAMN_WORK_NOW,10,40,100,20,"Debug Menu ID") 
    
    CreateThread(@ClearKeyBuffers(),0)
    CreateThread(@ShowHandle(),#Null)  
    
    Repeat
      
      F5=GetAsyncKeyState_(#VK_F5)
      If F5
        Delay(100) : If Pause : Pause=0 : Else : Pause=1 : EndIf
      EndIf
      
      Select WaitWindowEvent() 
        Case #PB_Event_Gadget 
          Select EventGadget() 
            Case #DAMN_WORK_NOW 
              handle = Val(GetClipboardText())
              
              Debug "Handle="+Str(handle)
              
              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) 
              
              zefix = -200 ; keine Ahnung wie ich das automatisch füllen soll !

              menu_item_id = GetMenuItemID_(menu_id,zefix) ; Bringt mir gar nichts !
              SendMessage_(handle,#WM_COMMAND,menu_item_id,main_menu_handle) ; geht nicht, siehe Zeile drüber ! 
              Debug "Menu Item ID="+Str(menu_item_id)
              

              SendMessage_(handle,#WM_COMMAND,0,main_menu_handle) ; FUNZT IN PAINT WEIL KEIN UNTERMENU
              
              
              
          EndSelect 
        Case #PB_Event_CloseWindow
          End 
      EndSelect 
      
    ForEver
    
  EndIf
Zuletzt geändert von N00B am 05.11.2013 16:12, insgesamt 3-mal geändert.
Benutzeravatar
N00B
Beiträge: 122
Registriert: 11.07.2007 22:28

Re: Menu mit Submenu über GetSubMenu ansprechen

Beitrag von N00B »

Hat niemand ne Idee, wie ich die ID von dem Menu Subelement rauskriege ? :freak:
Benutzeravatar
RSBasic
Admin
Beiträge: 8047
Registriert: 05.10.2006 18:55
Wohnort: Gernsbach
Kontaktdaten:

Re: Menu mit Submenu über GetSubMenu ansprechen

Beitrag von RSBasic »

In der PB-Hilfe steht zwar, dass OpenSubMenu() keinen Rückgabewert besitzt, aber du kannst die "ID" eines SubMenu trotzdem ganz einfach ermitteln:

Code: Alles auswählen

EnableExplicit

Define EventID

If OpenWindow(0, 0, 0, 500, 400, "Window", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
  If CreateMenu(1, WindowID(0))
    MenuTitle("Datei")
    MenuItem(1, "Neu")
    Debug OpenSubMenu("Öffnen")
    MenuItem(2, "Datei")
    CloseSubMenu()
    
  EndIf
  Repeat
    EventID = WaitWindowEvent()
    If EventID = #PB_Event_CloseWindow
      End
    EndIf
  ForEver
EndIf
Oder meinst du was anderes?
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: Menu mit Submenu über GetSubMenu ansprechen

Beitrag von N00B »

Erst mal Danke RSBasic :)

Mir geht's darum Submenu Elemente eines anderen Programmes (z.B Notepad2) mit

Code: Alles auswählen

SendMessage_(handle,#WM_COMMAND,UNBEKANNT,main_menu_handle)
anzusprechen.

Probiere ich PB Interne Befehle (an anderen Programmen) wie WindowID(x), HideWindow(x) usw
gibt's nenn PB Absturz, selbst wenn ich HideWindow(WindowID(handle))
benutzen würde d.H weiss ich das der Code von dir in diesem Fall nicht gehen wird.

Ich weiss das ich das Menu Handle des anderen Programmes per

main_menu_handle = GetMenu_(handle)

kriege, und per

menu_id = GetSubMenu_(main_menu_handle,2)

das Handle vom 3. Menü von links (ok der Name der Variable ist etwas bescheuert gewählt von mir)

kriege, und per

menu_item_id = GetMenuItemID_(menu_id,4)

das Handle (auch hier hab ich den Namen der Variable bescheuert gewählt)
vom 5. Item aus der 3.Menu Liste von links.

Aber welche Nummer ein Submenu hat, und wie ich die kriege oder errechne (haben die auch ein System wie Menu von links nach rechts, menu items von oben nach unten ?????) daß
weiss ich nicht.
Benutzeravatar
RSBasic
Admin
Beiträge: 8047
Registriert: 05.10.2006 18:55
Wohnort: Gernsbach
Kontaktdaten:

Re: Menu mit Submenu über GetSubMenu ansprechen

Beitrag von RSBasic »

N00B hat geschrieben:Probiere ich PB Interne Befehle wie wie WindowID(x), HideWindow(x) usw
gibt's nenn Absturz bei anderen Programmen, selbst wenn ich HideWindow(WindowID(handle))
So geht das leider nicht, weil die PB-Funktionen die interne PB-Nummer benötigen und nicht die Handle-Nummer.
Wenn du beispielsweise ein Fenster verstecken möchtest, musst du auf WinAPI zugreifen. Beispielcode fürs Verstecken eines Fensters:

Code: Alles auswählen

EnableExplicit

Define Handle

RunProgram("notepad.exe")
Delay(1000)
Handle = FindWindow_("notepad", #Null)
If Handle
  ShowWindow_(Handle, #SW_HIDE)
  Debug "Fenster wurde jetzt versteckt."
  Delay(1000)
  ShowWindow_(Handle, #SW_SHOW)
  Debug "Fenster wird jetzt wieder angezeigt."
Else
  Debug "Fenster konnte nicht gefunden werden."
EndIf
N00B hat geschrieben:Aber welche Nummer ein Submenu hat, und wie ich die kriege oder errechne (haben die auch ein System wie Menu von links nach rechts, menu items von oben nach unten ?????) daß
weiss ich nicht.
Möchtest du das komplette Menü von Notepad auslesen?
Kannst du mir sagen, was dein Ziel ist? Vielleicht kann man es auch anders machen. Möchtest du was bestimmtes auslesen oder was verändern oder verstecken o.ä.?
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: Menu mit Submenu über GetSubMenu ansprechen

Beitrag von N00B »

RSBasic hat geschrieben:
N00B hat geschrieben:Probiere ich PB Interne Befehle wie wie WindowID(x), HideWindow(x) usw
gibt's nenn Absturz bei anderen Programmen, selbst wenn ich HideWindow(WindowID(handle))
So geht das leider nicht, weil die PB-Funktionen die interne PB-Nummer benötigen und nicht die Handle-Nummer.
Wenn du beispielsweise ein Fenster verstecken möchtest, musst du auf WinAPI zugreifen. Beispielcode fürs Verstecken eines Fensters:

Code: Alles auswählen

EnableExplicit

Define Handle

RunProgram("notepad.exe")
Delay(1000)
Handle = FindWindow_("notepad", #Null)
If Handle
  ShowWindow_(Handle, #SW_HIDE)
  Debug "Fenster wurde jetzt versteckt."
  Delay(1000)
  ShowWindow_(Handle, #SW_SHOW)
  Debug "Fenster wird jetzt wieder angezeigt."
Else
  Debug "Fenster konnte nicht gefunden werden."
EndIf
Danke RSBasic :)

Das weis mit den PB internen Nummer weiss ich :) Ich habs nur mal probiert gehabt, weil die Fenstergröße per API ermitteln so verdammt umständlich ist (RECT Structure, x_pos - y_pos damit mann die Fenstergröße hat usw usw) und als das nicht ging (also PB Befehle für andere Progs, daß Fenstergröße ändern per API hab ich hingekriegt) bin ich automatisch von ausgegangen, daß andere Fenster & Button Befehle von PB nicht bei fremden Programmen
gehen.
N00B hat geschrieben:Aber welche Nummer ein Submenu hat, und wie ich die kriege oder errechne (haben die auch ein System wie Menu von links nach rechts, menu items von oben nach unten ?????) daß
weiss ich nicht.
Möchtest du das komplette Menü von Notepad auslesen?
Kannst du mir sagen, was dein Ziel ist? Vielleicht kann man es auch anders machen. Möchtest du was bestimmtes auslesen oder was verändern oder verstecken o.ä.?

Das währe eine Möglichkeit, aber dann hätte ich ja nur die Namen (den Befehl zum erfassen
des Namens kenn ich, aber auch da brauch ich dir korrekte Menu Element Angabe) und müsste wieder zig API Codes suchen & zusammenwürlfen, damit ich anhand der Namen die ID kriege.

Ich weiss das das Handle von Menüs sich immer ändert, sobald ein Menü zugeklappt wird, und wieder aufgeklappt hat es ein anderes Handle.

Leider sind mir keine Befehle bekannt, ausser GetMenu_( und GetSubMenu_(

GetSubMenu erfasst, nur Menüs von links nach rechts, jedenfalls bei meinen zig versuchen :(

Mein Ziel ist, ein Klick im Untermenü von Notepad2

http://de.wikipedia.org/wiki/Notepad2

zu erzeugen. (wenn ich es hinkriege, kriege ich es z.B auch beim AMD Power Monitor hin die Energieprofile umzuschalten)

Ich hab ein kleines Tool geschrieben, daß mir Strings an eine Zielanwendung sendet

(per SendMessage & #WM_PASTE oder Fenster der Zielanwendung Transparent machen, in den Vordergrund holen & ein STRG+V senden)

und dann Speichert

(entweder per Menu Klick "File"->"Save" oder Fenster der Zielanwendung Transparent machen, in den Vordergrund holen & ein STRG+S senden)

könnte ich aber Submenü Elemente ansprechen, könnte ich z.B das
"File"->"Encoding" Menü aufrufen, und das Encoding z.B auf "UTF8" umstellen, oder ein anderes kleines Tool schreiben, daß per Timer den AMD Power Monitor von Stromfress Modus in den Stromspar Modus schaltet, usw usw :)
Benutzeravatar
RSBasic
Admin
Beiträge: 8047
Registriert: 05.10.2006 18:55
Wohnort: Gernsbach
Kontaktdaten:

Re: Menu mit Submenu über GetSubMenu ansprechen

Beitrag von RSBasic »

Ah okay, nun weiß ich, was du genau machen möchtest.
Es ist einfacher, wenn du ein MenuItem-Event direkt simulierst, ohne jegliches Auslesen der einzelnen Menü-Elemente oder manuelles Aufklappen der Untermenüs.
Also sowas wie: http://www.rsbasic.de/aktualisierung/wi ... 3%B6sen.pb
Beispiel mit Notepad (Original), um das "Öffnen" zu simulieren:

Code: Alles auswählen

EnableExplicit

Define Handle

RunProgram("notepad.exe")
Delay(1000)
Handle = FindWindow_("notepad", #Null)
If Handle
  PostMessage_(Handle, #WM_COMMAND, 2, 0)
Else
  Debug "Fenster konnte nicht gefunden werden."
EndIf
Jeder Menüeintrag, egal in welchem Untermenü, hat eine eigene Eintragsnummer wie in PB. Auf diese Nummer kannst du zugreifen und in deinem Fall ein Klick-Event simulieren. Welche Nummer das ist, die du suchst, musst du selbst herausfinden und probieren. Vielleicht gibt es ein Tool, womit du das herausfinden kann. Ich kenne leider keins.
Aus privaten Gründen habe ich leider nicht mehr so viel Zeit wie früher. Bitte habt Verständnis dafür.
Bild
Bild
Benutzeravatar
RSBasic
Admin
Beiträge: 8047
Registriert: 05.10.2006 18:55
Wohnort: Gernsbach
Kontaktdaten:

Re: Menu mit Submenu über GetSubMenu ansprechen

Beitrag von RSBasic »

Ich habe mal Notepad2 x64 heruntergeladen und kurz getestet und herum probiert.
Hier ein Beispielcode, um das About-Fenster aufzurufen:

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
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: Menu mit Submenu über GetSubMenu ansprechen

Beitrag von N00B »

Danke für die Hilfe RSBasic, aber ich glaub das krieg ich nicht hin.

Ich bin mir ziehnmlich sicher

SendMessage_(fenster_handle,#WM_COMMAND,menu_item_id,main_menu_id)

ist das selbe in diesem Fall (es geht nur um Menüs aufrufen) wie Postmessage_(

und leider konnte ich auch kein Tools oder noch besser ein Code Snipet finden, daß mir
die benötigte ID ausgeben kann.

Hab ein Snippet gefunden gehabt (habs nicht mehr, hab ewig damit rumprobiert, und dann entnervt aufgegeben) hier im Board, daß mir den aktuellen Menü Namen
und die Nummer ID ausgibt, unterhalb der Maus, aber nicht das Handle des Menüs oder des Eintrags.

Bei

File,Edit,View,Settings,?
----------------------------------

File ist 0, Edit ist 1 usw

Unter File ist
"New" die 0
"Open" die 1
Die Menubar die 2 usw

aber sobald unter "File" das Untermenü "Launch" (ist die 8 sagt das Snippet) erreicht wird, und ich mit der Maus nach rechts rüberfahre in dieses Menü, ist der erste Eintrag "Launch New Window..." laut dem Snippet die Nr. 0

Was sich ändert ist nur das Handle des Menüs, sobald ich wieder rüberfahre zu "File" und wieder
rüber zu "Launch" ist das Menu Handle ein anderes.
RSBasic

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
Genau das selbe hatte ich auch schon mal :) 40000 ist das niedrigste Menü Element,
40001 ist New, 40002 ist open usw

Nur woher weiss ich, daß diese Zahlen fixe Werte sind, und nicht dynamisch ? :|

Wie auch immer, ich muss jetzt schlafen gehen.

Danke nochmals für die Hilfe :)
Benutzeravatar
RSBasic
Admin
Beiträge: 8047
Registriert: 05.10.2006 18:55
Wohnort: Gernsbach
Kontaktdaten:

Re: Menu mit Submenu über GetSubMenu ansprechen

Beitrag von RSBasic »

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.
Aus privaten Gründen habe ich leider nicht mehr so viel Zeit wie früher. Bitte habt Verständnis dafür.
Bild
Bild
Antworten