Dobrý den,
mám drobný dotaz ohledně metody CSalamanderGeneralAbstract::FocusNameInPanel(...)
v komentáři (SDK 2.51) je napsáno, že musí byt použita pouze v hlavním vlákně. Jak toho dosáhnu? Hlavní vlákno ve svém pluginu použiju jen ve chvíli, kdy uživatel klikne na položku menu v Salamanderu.
Struktura pluginu je:
hlavní vlákno:
- Zpracovává menu položku a založí UI vlákno
UI vlákno:
- vytvoří okno a pak ho obsluhuje pomocí své message loop
- pokud potřebuje, tak si založí pracovní vlákna
pomocná pracovní vlákna
- komunikují s UI vláknem pomocí sdílených zámků a posílaní WM_APP + n zpráv
Dotaz na CSalamanderGeneralAbstract::FocusNameInPanel
-
- ALTAP Staff
- Posts: 1112
- Joined: 08 Dec 2005, 09:13
- Location: Novy Bor, Czech Republic
- Contact:
Volani v hlavnim vlakne obvykle zajistujeme pres metodu PostMenuExtCommand. Doporucene schema provedeni prikazu Focus ve vieweru je patrne z nasledujiciho kodu (fileName je plne jmeno souboru pro focus v panelu, FocusPathBuf je globalni buffer o velikosti MAX_PATH, MENU_CMD_FOCUS je konstanta s cislem prikazu menu viz PostMenuExtCommand):
V metode CPluginInterfaceForMenuExt::ExecuteMenuItem osetrime prikaz MENU_CMD_FOCUS:
Code: Select all
if (SalamanderGeneral->SalamanderIsNotBusy(NULL))
{
lstrcpyn(FocusPathBuf, fileName, MAX_PATH);
SalamanderGeneral->PostMenuExtCommand(MENU_CMD_FOCUS, TRUE);
Sleep(500); // dojde k prepnuti do panelu, takze toto cekani bude v neaktivnim okne vieweru, tedy nicemu nevadi
FocusPathBuf[0] = 0; // po 0.5 sekunde uz o fokus nestojime (resi pripad, kdy jsme trefili zacatek BUSY rezimu Salamandera)
}
else
SalamanderGeneral->SalMessageBox(HWindow, LoadStr(IDS_SAL_IS_BUSY), TITLE_NAME, MB_ICONINFORMATION);
Code: Select all
case MENU_CMD_FOCUS:
{
char focusPath[MAX_PATH];
lstrcpyn(focusPath, FocusPathBuf, MAX_PATH);
FocusPathBuf[0] = 0;
if (focusPath[0] != 0) // jen pokud jsme nemeli smulu (netrefili jsme zacatek BUSY rezimu Salamandera)
{
LPTSTR name;
if (SalamanderGeneral->CutDirectory(focusPath, &name))
{
SalamanderGeneral->SkipOneActivateRefresh(); // hlavni okno pri prepnuti z viewru nebude delat refresh
SalamanderGeneral->FocusNameInPanel(PANEL_SOURCE, focusPath, name);
}
}
return TRUE;
}
-
- ALTAP Staff
- Posts: 1112
- Joined: 08 Dec 2005, 09:13
- Location: Novy Bor, Czech Republic
- Contact:
Jeste priklad chybove hlasky:
Code: Select all
IDS_SAL_IS_BUSY, "Altap Salamander is busy. The requested command cannot be accomplished, please try it again later."
Díky! Sice je to krkolomné řešení, ale funguje
Šlo by do budoucna toto nějak vyřešit čistěji? (založit metodu pro příjem zpráv v hlavním vlákně včetně nějakého lParam, abychom se zbavili globálních proměnných)
Aby se neměnilo rozhranní, tak by možná stačilo přidat jen možnost posílat zprávy do existující a povinné CPluginInterface::Event(int event, DWORD param) metody. Jen by mohlo hrozit, že by ID události pluginu kolidovalo s budoucím ID nové události Salamandera...
Šlo by do budoucna toto nějak vyřešit čistěji? (založit metodu pro příjem zpráv v hlavním vlákně včetně nějakého lParam, abychom se zbavili globálních proměnných)
Aby se neměnilo rozhranní, tak by možná stačilo přidat jen možnost posílat zprávy do existující a povinné CPluginInterface::Event(int event, DWORD param) metody. Jen by mohlo hrozit, že by ID události pluginu kolidovalo s budoucím ID nové události Salamandera...
-
- ALTAP Staff
- Posts: 1112
- Joined: 08 Dec 2005, 09:13
- Location: Novy Bor, Czech Republic
- Contact:
Urcite by to slo, jeste mi to par lidi zopakuje (nejsi prvni) a pujdu to napsat. Je tam trochu potiz s tim parametrem, pokud by to bylo neco alokovaneho (nebo treba otevreny handle souboru), je potreba nejak vyresit dealokaci/zavreni v pripade, ze se to nestihne dorucit (drive dojde k unloadu pluginu).
Zatim jsem potrebu parametru obchazel takto: udelas si globalni pole struktur, ktery obsahuji vsechny potrebne parametry (klidne alokovane retezce, atd.), kdyz chces postnout prikaz, nejprve naplnis jednu polozku do toho pole, a pak teprve postnes prikaz (s jednim vybranym ID), az prikaz dojde, vyzvednes si tu polozku z pole a s ni vsechny parametry, a pak prvek pole zrusis. Kdyz dojde k unloadu pluginu, zrusis vsechny zbyle prvky pole (tim se elegantne resi ten zmineny problem s unloadem). Prirozene muzes pri prijmu prikazu vycerpat vsechny prvky pole, aby se provedly co nejdrive, pri prijmu dalsich prikazu menu uz pak nebudes delat nic (pole bude prazdne). Pokud by tech prikazu bylo enormni mnozstvi, muzes i tohle vyoptimalizovat (neposilat dalsi prikaz se stejnym ID dokud predchozi odeslany nedorazil).
Zatim jsem potrebu parametru obchazel takto: udelas si globalni pole struktur, ktery obsahuji vsechny potrebne parametry (klidne alokovane retezce, atd.), kdyz chces postnout prikaz, nejprve naplnis jednu polozku do toho pole, a pak teprve postnes prikaz (s jednim vybranym ID), az prikaz dojde, vyzvednes si tu polozku z pole a s ni vsechny parametry, a pak prvek pole zrusis. Kdyz dojde k unloadu pluginu, zrusis vsechny zbyle prvky pole (tim se elegantne resi ten zmineny problem s unloadem). Prirozene muzes pri prijmu prikazu vycerpat vsechny prvky pole, aby se provedly co nejdrive, pri prijmu dalsich prikazu menu uz pak nebudes delat nic (pole bude prazdne). Pokud by tech prikazu bylo enormni mnozstvi, muzes i tohle vyoptimalizovat (neposilat dalsi prikaz se stejnym ID dokud predchozi odeslany nedorazil).