wchar_t
Самое очевидное изменение: Far 2.0 - юникодный, поэтому char везде заменяется на wchar_t.
Экспорт функций
Раньше экспорт функций нужно было прописывать в коде плагина вручную:
extern "C" { void WINAPI _export SetStartupInfoW(struct PluginStartupInfo const* Info); HANDLE WINAPI _export OpenPluginW(int OpenFrom,int Item); ... }Теперь экспорт всех функций прописан в стандартном файле "plugin.hpp".
Изменились, так же, сигнатуры некоторых функций. В частности: PutFilesW, OpenPluginW, SetStartupInfoW, MakeDirectoryW и т.д.
Функция Control
Изменилась функция Control:
int WINAPI Control(HANDLE hPlugin, int Command, void *Param); //Far 1.X int WINAPI Control(HANDLE hPlugin, int Command, int Param1, LONG_PTR Param2); //Far 2.XСоответственно, изменились и вызовы:
extern struct PluginStartupInfo g_PluginInfo; //Far 1.X std::string dir_oem; g_PluginInfo.Control(INVALID_HANDLE_VALUE , bActivePanel ? FCTL_SETPANELDIR : FCTL_SETANOTHERPANELDIR , (void*)dir_oem.c_str()); //Far 2.X std::wstring dir; g_PluginInfo.Control( (bActivePanel ? PANEL_ACTIVE : PANEL_PASSIVE) , FCTL_SETPANELDIR , 0 , reinterpret_cast<LONG_PTR>(dir.c_str()));
Структура PanelInfo
В PanelInfo пропали некоторые поля, например ColumnTypes, ColumnWidths, CurDir - код нужно изменять. Пример:
//Far 1.X PanelInfo& panel_info = plugin.GetPanelInfo(true) std::string cur_dir = panel_info.CurDir; //Far 2.X extern struct PluginStartupInfo g_PluginInfo; std::wstring GetPanelCurDir(bool bActivePanel) { wchar_t buffer[1024]; if (! g_PluginInfo.Control( (bActivePanel ? PANEL_ACTIVE : PANEL_PASSIVE) , FCTL_GETPANELDIR , 1024 , reinterpret_cast<LONG_PTR>(&buffer[0]) )) return L""; return reinterpret_cast<whcar_t const*>(&buffer[0]); } std::wstring cur_dir = GetPanelCurDir(true);Кроме того, из PanelInfo исчезли поля PanelItems и SelectedItems. Нужен список выделенных элементов панели? Придется написать что-то типа:
extern struct PluginStartupInfo g_PluginInfo; PluginPanelItem* allocate_PluginPanelItem(HANDLE hplugin , int Command, int nSelectedItem) { PluginPanelItem* ppi = reinterpret_cast<PluginPanelItem*>( malloc(g_PluginInfo.Control(hplugin, Command, nSelectedItem, NULL))); g_PluginInfo.Control(hplugin, Command, nSelectedItem , reinterpret_cast<LONG_PTR>(ppi)); return ppi; } void deallocate_PluginPanelItem(PluginPanelItem* p) { free(p); } ... PluginPanelItem *ppi = allocate_PluginPanelItem(pPanel , FCTL_GETSELECTEDPANELITEM, nSelectedItem); std::wstring file_name = ppi->FindData.lpwszFileName; .. deallocate_PluginPanelItem(ppi);
FarDialogItem
В FarDialogItem два серьезных изменения. Во-первых, массив char Data[512] заменен на const wchar_t *PtrData. Т.е. строка инициализации элемента диалога более не хранится в FarDialogItem, хранится только указатель на нее. А это значит, что саму строку придется хранить где-то еще. Если у вас есть массив структур FarDialogItem, вам потребуется завести дополнительный массив строковых буферов.
Во-вторых, ранее, после закрытия диалога, в FarDialogItem сохранялись результирующие значения. Т.е через поля FarDialogItem можно было получить измененный текст, измененное значение флага checkbox и т.д. Теперь структура FarDialogItem является неизменной. А измененные значения получают через SendDlgMessage:
Far 2.X: //get modified data from dialog after dialog closing extern struct PluginStartupInfo g_PluginInfo; HANDLE m_DialogHandle = g_PluginInfo.DialogInit(...) std::wstring GetDialogItemValue(int dialogItemId) { assert(m_DialogHandle != 0); FarDialogItemData fdi; fdi.PtrLength = g_PluginInfo.SendDlgMessage(m_DialogHandle , DM_GETTEXTLENGTH, dialogItemId, 0); std::wstring buffer; buffer.resize(fdi.PtrLength + 1); fdi.PtrData = &buffer[0]; fdi.PtrData[0] = L'0'; g_PluginInfo.SendDlgMessage(m_DialogHandle, DM_GETTEXT , dialogItemId, reinterpret_cast<LONG_PTRY>(&fdi)); return fdi.PtrData; } bool IsDialogItemSelected(int dialogItemId) { assert(m_DialogHandle != 0); return g_PluginInfo.SendDlgMessage(m_DialogHandle , DM_GETCHECK, dialogItemId, 0) == BSTATE_CHECKED; }
Вызов диалога
Вместо функций Dialog и DialogEx теперь нужно использовать DialogInit, DialogFree, DialogRun и объявлять собственную DlgProc.
Far 2.X: extern struct PluginStartupInfo g_PluginInfo; static LONG_PTR WINAPI dlg_proc(HANDLE hDlg, int Msg , int Param1, LONG_PTR Param2) { return g_PluginInfo.DefDlgProc(hDlg, Msg , Param1, Param2); } ... //инициализация списка элементов диалога FarDialogItem* dialog_items = ...; int dialog_items_count = ...; HANDLE hdlg = g_PluginInfo.DialogInit( g_PluginInfo.ModuleNumber , -1 , -1 , 20 //dialog width , 5 //dialog height , NULL //help topic , dialog_items , dialog_items_count , 0 //reserved , 0 //flags , &::dlg_proc , 0 //param ); int nChoosenItem = g_PluginInfo.DialogRun(hdlg); g_PluginInfo.DialogFree(hdlg);
Резюме
В целом, изменений не так много. Самое неприятное - пришлось заводить буферы для хранения строк для FarDialogItem. Вначале думал завести структуру FarDialogItem_wrapper, в которой хранить рядом FarDialogItem и буфер. Не получилось, т.к. во многих случаях требуется передавать в FAR массивы элементов FarDialogItem, и врапперы здесь не проходят. Так что теперь приходится в коде поддерживать два параллельных массива - FarDialogItem и boost::shared_ptr<std::wstring>.
Комментариев нет:
Отправить комментарий