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>.
Комментариев нет:
Отправить комментарий