Page 2 of 2

Posted: 09 Mar 2009, 04:01
by zarevak
Tak jsem mrknul do uniklých zdrojáků Windows 2000 a TrackPopupMenu je implementované tak, že pracuje přímo s interními strukturami Windows. Tedy:

Code: Select all

for (cItem = 0; cItem < pMenu->cItems; cItem++) {
...
}
Dokonce se nikdy celé menu již nijak nezpracovává. Jen se při prvním průchodu spočítá velikost položek (a tím velikost menu). Pak už jen při zpracování WM_PAINT jsou položky procházeny znova a podle potřeby kresleny.

Nevěřím, že by TrackPopupMenu bylo ve WinXP implementováno nějak výrazně odlišně, takže se bojím, že zde nic nevykoumáme :(


Na druhou stranu GetMenuItemInfo s fByPosition == true funguje čistě na způsob pMenu->cItems[uItem];
Je divné, že GetMenuItemInfo vrátí ERROR_INVALID_MENU_HANDLE, protože toto je možné vrátit jen pro hMenu jako takové a pokud předchozí položky fungovaly, tak hMenu je stále platné (neplatná kombinace hMenu a uItem vrací ERROR_MENU_ITEM_NOT_FOUND).
Pokud jsem to pochopil špatně a GetMenuItemInfo vrací ERROR_INVALID_MENU_HANDLE až pro hMenu LiveMeshího submenu, pak je pravda, že jedna z kontrol platnosti hMenu je nějaká kontrola práv...


Mimochodem: Je zajímavé, kolik je ve zdrojáku poznámek ve stylu "Kvůli programu ABC je třeba zachovat tenhle bug, protože to jinak nebude fungovat." spojeno jen s menu.

Posted: 09 Mar 2009, 09:04
by Jan Rysavy
V nejvyšší úrovni context menu vrátí GetMenuItemInfo() pro pozici 6 (tam je na mém počítači LiveMesh submenu, viz mé fotky obrazovek) v hodnotě mii.hSubMenu nějaké zdánlivě validní číslo. Pokud se doptám na string, vrátí korektně "&Live Mesh Options".

Chyba nastane až ve chvíli, kdy se pokusím vrácené mii.hSubMenu zkoumat pomocí funkce GetMenuItemCount(mii.hSubMenu). Zkusil jsem vrácené submenu zobrazit pomocí TrackPopupMenu() nebo zkoumat pomocí IsMenu() či AppendMenu() a také neúspěch. Zkrátka to není validní handle submenu.

Přikládám zmíněný testík, je to takový slepenec ze samplů, tak se nelekni. Mrkni na obě FIXME, je potřeba nastavit cestu k LiveMesh adresáři a na druhém nastavit breakpoint. Potom už stačí pravým tlačítkem kliknout od plochy samplu pro vybalení menu.

Posted: 12 Mar 2009, 20:14
by manison
Trochu jsem se na to podíval, a ten handle je zničený (má příznak HANDLEF_DESTROY). Vyplnil jsem bug report.

Posted: 12 Mar 2009, 20:23
by Jan Rysavy
Čím lze stav handle detekovat?

Posted: 12 Mar 2009, 20:47
by manison
Bohužel pouze pomocí debuggeru, disassembleru, Googlu a s pomocí uniklých zdrojáků W2k sloužících jako zastaralá dokumentace :)

Posted: 12 Mar 2009, 20:54
by Jan Rysavy
AHA :)

Díky moc za posun!