Dotaz na CSalamanderGeneralAbstract::FocusNameInPanel

Podpora vývojářů nových pluginů, oznámení o nových pluginech nezávislých autorů a diskuse o nich.
User avatar
zarevak
Plugin Developer
Plugin Developer
Posts: 789
Joined: 04 Feb 2006, 16:49
Location: Prague, Czech Republic

Dotaz na CSalamanderGeneralAbstract::FocusNameInPanel

Post by zarevak »

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
Petr Solin
ALTAP Staff
ALTAP Staff
Posts: 1112
Joined: 08 Dec 2005, 09:13
Location: Novy Bor, Czech Republic
Contact:

Post by Petr Solin »

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):

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);
V metode CPluginInterfaceForMenuExt::ExecuteMenuItem osetrime prikaz MENU_CMD_FOCUS:

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;
}
Petr Solin
ALTAP Staff
ALTAP Staff
Posts: 1112
Joined: 08 Dec 2005, 09:13
Location: Novy Bor, Czech Republic
Contact:

Post by Petr Solin »

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."
User avatar
zarevak
Plugin Developer
Plugin Developer
Posts: 789
Joined: 04 Feb 2006, 16:49
Location: Prague, Czech Republic

Post by zarevak »

Díky! Sice je to krkolomné řešení, ale funguje 8)

Š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...
Petr Solin
ALTAP Staff
ALTAP Staff
Posts: 1112
Joined: 08 Dec 2005, 09:13
Location: Novy Bor, Czech Republic
Contact:

Post by Petr Solin »

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).
Post Reply