| View previous topic :: View next topic |
| Author |
Message |
private_joker
Joined: 28 May 2010 Posts: 62
|
Posted: Thu Jul 29, 2010 3:30 pm Post subject: Вопросы по AkelPad Plugin API. |
|
|
Тут будут вопросы по AkelPad Plugin API.
Есть ли способ заменить весь текст в текущем эдит контроле без предварительного выделения с помощью IDM_EDIT_SELECTALL и последующего AKD_REPLACESEL. В принципе у меня работает и так, но я не уверен насчет производительности и необходимости этого выделения.
P.S. Естественно я имею ввиду нативный C/C++ код. |
|
| Back to top |
|
 |
FeyFre
Joined: 07 Aug 2007 Posts: 1889 Location: Vinnitsa, Ukraine
|
Posted: Thu Jul 29, 2010 3:48 pm Post subject: |
|
|
private_joker
Способ номер раз:
EM_SETSEL (0,-1) + EM_REPLACESEL (выделение и замена) непосредственно контролу, а не через главное окно
Способ номер двас(простой как воздух, но незаслуженно забытый):
WM_SETTEXT контролу без никаких предварительных выделений
По вопросам производительности обращайтесь к for и QueryPerformanceCounter и сравнивайте быстродействие сколько Вам угодно. |
|
| Back to top |
|
 |
private_joker
Joined: 28 May 2010 Posts: 62
|
Posted: Thu Jul 29, 2010 6:24 pm Post subject: |
|
|
| FeyFre wrote: |
По вопросам производительности обращайтесь к for и QueryPerformanceCounter и сравнивайте быстродействие сколько Вам угодно. |
Вопрос был совсем не об этом.
| FeyFre wrote: |
Способ номер двас(простой как воздух, но незаслуженно забытый):
WM_SETTEXT контролу без никаких предварительных выделений
|
Этот способ не подходит, т.к. обнуляет буфер отмены. Что как ты (наверное) можешь заметить не является естественным и ожидаемым действием для программы.
| FeyFre wrote: |
Способ номер раз:
EM_SETSEL (0,-1) + EM_REPLACESEL (выделение и замена) непосредственно контролу, а не через главное окно
|
А вот это посмотрю, благодарю. |
|
| Back to top |
|
 |
Fr0sT
Joined: 24 Jul 2007 Posts: 850
|
Posted: Wed Jan 18, 2012 2:02 pm Post subject: |
|
|
У меня вопрос по AKD_GETFRAMEINFO. Я правильно понимаю, что через него можно получить только одно значение зараз? Проглядел сорсы Акеля, вроде бы так и есть. В таком случае получается странновато: какой смысл передавать целую структуру, если возвращается только одно поле, да и то всегда в dwData.
Было бы удобнее, если бы функция на самом деле принимала комбинацию флагов (и заполняла соответствующие поля структуры FRAMEDATA), как это указано в AkelDLL.h |
|
| Back to top |
|
 |
Instructor Site Admin
Joined: 06 Jul 2006 Posts: 4640
|
Posted: Wed Jan 18, 2012 3:02 pm Post subject: |
|
|
Fr0sT
Все элементы структуры итак доступны плагинам через сообщения AKD_FRAME*. Главное назначение AKD_GETFRAMEINFO - использование в скриптах. |
|
| Back to top |
|
 |
Fr0sT
Joined: 24 Jul 2007 Posts: 850
|
Posted: Wed Jan 18, 2012 3:25 pm Post subject: |
|
|
Ясно. А получить данные из текущего фрейма можно через
AKD_FRAMEFIND + FWF_CURRENT? |
|
| Back to top |
|
 |
VladSh
Joined: 29 Nov 2006 Posts: 2509 Location: Киев, Русь
|
Posted: Wed Jan 18, 2012 4:58 pm Post subject: |
|
|
Fr0sT
Чуток вышло: FileTabs.js. |
|
| Back to top |
|
 |
Fr0sT
Joined: 24 Jul 2007 Posts: 850
|
Posted: Wed Jan 18, 2012 7:31 pm Post subject: |
|
|
VladSh
Спасибо! Правда, оказалось, что мне вполне хватит DOCINFO) |
|
| Back to top |
|
 |
Fr0sT
Joined: 24 Jul 2007 Posts: 850
|
Posted: Mon Mar 12, 2012 3:30 pm Post subject: |
|
|
Как устроены параметры вызова функций плагина? Смотрел ContextMenu в качестве примера, но из этого
| Code: | BOOL IsExtCallParamValid(LPARAM lParam, int nIndex)
{
if (*((INT_PTR *)lParam) >= (INT_PTR)((nIndex + 1) * sizeof(INT_PTR)))
return TRUE;
return FALSE;
}
INT_PTR GetExtCallParam(LPARAM lParam, int nIndex)
{
if (*((INT_PTR *)lParam) >= (INT_PTR)((nIndex + 1) * sizeof(INT_PTR)))
return *(((INT_PTR *)lParam) + nIndex);
return 0;
}
|
Ни фига не понял.
Ясно, что PLUGINDATA.lParam - это указатель, а вот дальше тёмный лес |
|
| Back to top |
|
 |
DV
Joined: 16 Nov 2006 Posts: 723 Location: Kyiv, Ukraine
|
Posted: Mon Mar 12, 2012 4:40 pm Post subject: |
|
|
| Fr0sT wrote: | | Как устроены параметры вызова функций плагина |
Считаем, что lParam - это указатель на массив из элементов INT_PTR (т.е. массив, элементы которого являются INT_PTR). При этом самый первый элемент (с индексом 0) - это количество элементов в массиве, включая и этот самый первый элемент. Например, если передаются три параметра, то значение элемента с индексом 0 равно 3+1=4.
Специфика C такова, что со структурой, состоящей из INT_PTR, можно работать точно так же, как с массивом из того же кол-ва элементов. Т.е.
struct tMyStruct {
INT_PTR size;
INT_PTR i1;
INT_PTR i2;
INT_PTR i3;
} MyStruct;
аналогична
INT_PTR MyArray[4];
При этом нулевой элемент - т.е. size или MyArray[0] в нашем случае должен быть равен 4, указывая на то, что передаются 3 параметра + размер как нулевой параметр.
И lParam = (LPARAM) &MyStruct или же lParam = (LPARAM) MyArray. |
|
| Back to top |
|
 |
Fr0sT
Joined: 24 Jul 2007 Posts: 850
|
Posted: Mon Mar 12, 2012 4:53 pm Post subject: |
|
|
| DV, ага, ясно. А элементы массива (i1/2/3)? Они сами - указатели на параметры, насколько я понял. А если параметр - число? |
|
| Back to top |
|
 |
DV
Joined: 16 Nov 2006 Posts: 723 Location: Kyiv, Ukraine
|
Posted: Mon Mar 12, 2012 6:58 pm Post subject: |
|
|
Fr0sT,
Пример:
| Code: | DWORD dwParam1;
LPCTSTR pszParam2;
int nParam3;
// сами параметры
dwParam1 = 0xFFFFFFFF;
pszParam2 = _T("Abc");
nParam3 = 10;
// передача в структуру
MyStruct.size = 4;
MyStruct.i1 = dwParam1;
MyStruct.i2 = (INT_PTR) pszParam2;
MyStruct.i3 = nParam3;
// передача в массив
MyArray[0] = 4;
MyArray[1] = dwParam1;
MyArray[2] = (INT_PTR) pszParam2;
MyArray[3] = nParam3;
|
Ну и напоследок: поскольку размер INT_PTR, как и DWORD_PTR, равен размеру указателя (т.е. 4 байта для х86 или 8 байт для х64), а LPCTSTR, в свою очередь, тоже является указателем, можно объявить структуру
| Code: | struct tMyStruct2 {
INT_PTR size;
DWORD_PTR param1;
LPCTSTR param2;
INT_PTR param3;
} MyStruct2; |
которая с точки зрения памяти и расположения элементов является идентичной предыдущей tMyStruct. Для этой tMyStruct2 можно задавать параметры dwParam1, pszParam2 и nParam3 без приведения типов - и в то же время её точно так же можно привести к массиву из INT_PTR.
(Добавлено позднее)
В свете вышесказанного можно сослаться на реальный кусок кода из QSearchDlg.c - см. функцию qsearchDoTryUnhighlightAll. В ней используется структура DLLECHIGHLIGHT_UNMARK, объявленная как
| Code: | typedef struct sDLLECHIGHLIGHT_UNMARK {
UINT_PTR dwStructSize;
INT_PTR nAction;
UINT_PTR dwMarkID;
} DLLECHIGHLIGHT_UNMARK; |
Далее первая же строчка кода убеждает нас в том, что ранее я допустил неточность. Эта строчка
| Code: | | hlParams.dwStructSize = sizeof(DLLECHIGHLIGHT_UNMARK); |
записывает в самый первый (нулевой) параметр не 3 по общему количеству параметров, а размер структуры, равный 3*sizeof(INT_PTR). Ну а дальше - ловкость рук, и никакого мошенства. |
|
| Back to top |
|
 |
FeyFre
Joined: 07 Aug 2007 Posts: 1889 Location: Vinnitsa, Ukraine
|
Posted: Mon Mar 12, 2012 10:53 pm Post subject: |
|
|
| Quote: | | Специфика C такова, что со структурой, состоящей из INT_PTR, можно работать точно так же, как с массивом из того же кол-ва элементов. | Вот тут я бы очень даже не согласился. Ибо это очень частный случай, когда на память выделенную "под массив" можно наложить структуру, и все будет хорошо. На практике, дело упирается в обстоятельство именуемое "выравнивание".
"Грузить" могу много, но кратко скажу: АР, а также большинство плагов(мои тоже) работают на честном слове, ибо нигде явно не задается выравнивание полей в торчащих наружу структурах. Выравнивание унаследуется от умолчания компилятора, или от какого-нибудь хидера который об этом подумал, и чудом что у нас соблюдается ABI совместимость.
Так что стоит повнимательнее объявлять структуру накладываемую на lParam, ибо можно промахнуться и в лучшем случае "сделать что-то не то", в хужем - запороть вызывающему стэк или вообще поймать 0xC0000005. |
|
| Back to top |
|
 |
Fr0sT
Joined: 24 Jul 2007 Posts: 850
|
Posted: Tue Mar 13, 2012 6:22 am Post subject: |
|
|
Так... поправьте меня, если ошибаюсь: элементы №1..N могут содержать как указатель на строку, если параметр строковый, так и непосредственно число, если параметр числовой. Способов различить тип данных, хранящихся в ячейке, не существует, поэтому порядок параметров жёстко фиксирован и соблюдается под честное слово (стоит вместо ("bla", 0) передать (0, "bla") - словим AV на null pointer).
Имхо, неплохо было бы это зафиксировать где-то в мануалах, а ещё лучше - завернуть в функции в AkelDLL, выставив наружу только ParamCount и GetParam(idx).
P.S. Пост №666
UPD
Вызываю так (Toolbar):
"" Call("FileInfo::Main", "lala") Icon("%a\AkelFiles\Plugs\FileInfo.dll", 0)
Получаю:
INT_PTR(Pointer(pd.lParam)^) = 8. Wtf? |
|
| Back to top |
|
 |
VladSh
Joined: 29 Nov 2006 Posts: 2509 Location: Киев, Русь
|
Posted: Tue Mar 13, 2012 7:26 am Post subject: |
|
|
Fr0sT
Значит в 0-м параметре надо хранить не только общее количество, но и "массив" идентификаторов типов  |
|
| Back to top |
|
 |
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|