|
v8: скроллбары и WinAPI | ☑ | ||
---|---|---|---|---|
0
Вуглускр1991
30.03.13
✎
23:53
|
Получил иерархию окон, WNDCLASSEX структуру для каждого класса окон. Заслал в окна сообщения "скроллбары переместить в конец". Но стоят они упорные в начале. Вероятно 1С написали собственный скроллбарконтрол. Как долезть, в какое окно что послать?
(V8TopLevelFrameSDIsec, ВнешняяОбработка1 - Управление торговлей, редакция 10.3) (V8LayouterTabsWindow, ) (V8FormElement, ) (V8LayouterTabsWindow, ) (V8FormElement, ) (V8Grid, ) (V8FormElement, ) (V8FormElement, ) (V8FormElement, ) (V8LayouterTabsWindow, ) (V8FormElement, ) (V8LayouterTabsWindow, ) (V8FormElement, ) (V8FormElement, ) (V8FormElement, ) (V8FormElement, ) (V8FormElement, ) (V8FormElement, ) (V8ViewSplitter, ) (V8ViewSplitter, ) (V8ViewSplitter, ) (V8ViewSplitter, ) (V8AutoHideLayouter, ) (V8AutoHideLayouter, ) (V8AutoHideLayouter, ) (V8AutoHideLayouter, ) (V8CommandBar, ) (V8CommandBar, ) (V8CommandBar, ) (V8CommandBar, ) (V8Dockbar, ) (V8Dockbar, ) (V8Dockbar, ) (V8CommandBarDockFrame, ) (V8CommandBar, ) (V8CommandBarDockFrame, ) (V8CommandBar, ) (V8CommandBarDockFrame, ) (V8CommandBar, ) (V8CommandBarDockFrame, ) (V8CommandBar, ) (V8Dockbar, ) (V8CommandBarDockFrame, ) (V8CommandBar, ) (V8CommandBarDockFrame, ) (V8CommandBar, ) (V8CommandBarDockFrame, ) (V8CommandBar, ) (V8CommandBarDockFrame, ) (V8CommandBar, ) (V8CommandBarDockFrame, ) (V8CommandBar, ) (V8CommandBarDockFrame, ) (V8CommandBar, ) (V8CommandBarDockFrame, ) (V8CommandBar, ) (V8CommandBar, ) (V8FormElement, ) |
|||
1
Андрюха
31.03.13
✎
00:56
|
Что за муть в коде?
|
|||
2
Jaap Vduul
31.03.13
✎
01:56
|
если правильно понял о чём речь, то в окно V8Grid событие WM_KEYDOWN с параметром VK_END
|
|||
3
Вуглускр1991
31.03.13
✎
10:06
|
(2) Спасибо, сейчас попробую ...
|
|||
4
Вуглускр1991
31.03.13
✎
11:23
|
Увы, не взлетело
resSCR = ::PostMessage(ch1, WM_HSCROLL ,SB_ENDSCROLL,NULL); resSCR = ::PostMessage(ch1, WM_VSCROLL ,SB_ENDSCROLL,NULL); ни это UINT lparam1 = ::MapVirtualKey(VK_END, 0) << 16 | 1; UINT lparam2 = 1 << 31 | 1 << 30 | MapVirtualKey(VK_END, 0) << 16 | 1; resSCR = ::PostMessage(ch1, WM_KEYDOWN, VK_END, lparam1 ); resSCR = ::PostMessage(ch1, WM_KEYUP, VK_END, lparam2); ни это |
|||
5
Gluk
31.03.13
✎
11:29
|
Как я понял 1С пишет свои контролы, тоже никак не получается с ними работать.
|
|||
6
TormozIT
гуру
31.03.13
✎
11:57
|
Я тоже делал пару мощных подходов к порабощению контролов 1С8 через отсылку им событий. Тоже не удалось таким образом достичь успеха. В итоге делал все через SendKeys. Вот кусок кода
ActivateAppWindow(hMainWnd); Sleep(30); SendMessage(hV8Grid, WM_ACTIVATE , WA_CLICKACTIVE, NULL); HWND TargetWnd = hV8MDILocalFrame; DWORD tw = GetWindowThreadProcessId(TargetWnd, NULL); BOOL Result1 = AttachThreadInput(tw, GetCurrentThreadId(), TRUE); HWND result2 = SetFocus(hV8Grid); DWORD LastError = GetLastError(); HWND ActiveControl = GetFocus(); AttachThreadInput(tw, GetCurrentThreadId(), FALSE); if (ActiveControl != hV8Grid) return; if (ActType == act_open) return; HWND hModuleWindow; HWND hGotoLineWindow; WORD MKey; HKL layout; switch (ActType) { case act_open_module: sk.SendKeys("{TAB}{DELAY=100}{ENTER}{DOWN}{ENTER}"); hModuleWindow = WaitForOpenedFileModuleDialog(hV8MDIClient); if (hModuleWindow == NULL) return; sk.SendKeys("^+{ADD}"); if (TextOfLineNumber == NULL) break; if (stricmp(TextOfLineNumber, "") == 0) break; // Один из случаев срабатывает. От чего зависит пока не нашел. sk.SendKeys("^п"); sk.SendKeys("^g"); hGotoLineWindow = WaitForGotoLineDialog(hMainWnd); if (hGotoLineWindow == NULL) return; PasteTextInActiveControl(TextOfLineNumber); sk.SendKeys("{ENTER}"); break; case act_unit: sk.SendKeys("{TAB}{DELAY=100}{ENTER}{UP}{UP}{UP}{UP}{ENTER}"); if (ProcessOpenDialog(hMainWnd, ObjectName2) == FALSE) return; break; case act_open_form: sk.SendKeys("+{TAB}^+{F4}"); break; } |
|||
7
Jaap Vduul
31.03.13
✎
15:13
|
(4)
Специально проверил, работает: [DllImport("user32.dll", SetLastError = true)] [return: MarshalAs(UnmanagedType.Bool)] static extern bool PostMessage(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam); uint WM_KEYDOWN = 0x100; var VK_END = new IntPtr(0x23); bool result = PostMessage(hwnd, WM_KEYDOWN, VK_END, IntPtr.Zero); |
|||
8
Вуглускр1991
31.03.13
✎
16:49
|
(7) Я из (6) и из твоего поста понял, что работать будет, если hwnd - это текстовое поле на форме. В нем есть текст и он не помещается в экран, соответственно скроллбары имеют верхнее и нижнее положение.
Я на форму размером 200 на 320 вставляю декорацию, которая туда помещается, но платформа рисует скроллбары. Там нет текста и даже с клавиатуры я скроллбарами не рулю. Какие бы я клавиши не нажимал, управлять ими возможно только при помощи мыши. Теперь я пытаюсь посылать в окна WM_LBUTTONDOWN и WM_LBUTTONUP, курсор уже перемещается в нужную точку, но события пока не прут. Клавиатурой тут вообще ничего не сделаешь. http://s018.radikal.ru/i502/1303/e2/cbbc09b54f51.jpg |
|||
9
oleg_km
31.03.13
✎
17:08
|
(8) А трассировку сообщений посмотреть Spy++?
|
|||
10
Вуглускр1991
31.03.13
✎
17:25
|
(9) Вот прям сейчас и смотрю.
Вывод пока такой: для того, чтобы события отработали, есть некоторый протокол. Нельзя взять мышь и из ниоткуда воткнуть в окно, возможно нужена последовательная смена окон, переходы через границы, на основании этих данных платформа устанавливает фокус и капчу, только те события, которые укладываются в логику приложения отрабатываются оконной процедурой. Есть такое окно (даже два! по числу открытых форм), класса: V8ValidationMessageWnd похоже, что вот это ж-ж-ж неспроста. |
|||
11
Злопчинский
31.03.13
✎
17:29
|
(8) крайне неэффективное использование окна. нахрена в окне титул...?
|
|||
12
Вуглускр1991
31.03.13
✎
17:35
|
(11) А ты знаешь, чем я занимаюсь :)
а как его уберешь?? Я уж мучился на эту тему, решил писать суть операции вместо "Заголовок формы". Но то окошко, где MAXIMIZE и крестик, его я тоже не могу убрать. |
|||
13
Jaap Vduul
31.03.13
✎
17:47
|
(8)
Надо посылать WM_NCLBUTTONDOWN с параметром 1A для горизонтального скроллбара и 1B для вертикального. |
|||
14
Вуглускр1991
31.03.13
✎
18:03
|
(13) Спасибо! Ты прав! Я вот так дополз:
int resSCR = 0; resSCR = ::SetCursorPos(233,270); int SMsgRes = 0; SMsgRes = ::SendMessage(ch1, WM_NCHITTEST, 0, 0x010E00E9); resSCR = ::SendMessage(ch1, WM_NCLBUTTONDOWN ,SMsgRes,0x010E00E9); resSCR = ::SendMessage(ch1, WM_NCLBUTTONUP ,SMsgRes,0x010E00E9); Только что получилось !!! |
|||
15
oleg_km
31.03.13
✎
18:34
|
(14) Ну вроде логично: это же скролбар неклиентской части окна
|
|||
16
Злопчинский
31.03.13
✎
19:05
|
а стиль окна никак не поменять - убрать титул (как это можно вклюшках)...?
|
|||
17
Злопчинский
31.03.13
✎
19:06
|
или титул оставить, но убрать из него всю эту шнягу и в титул выводить полезную инфу?
|
|||
18
Злопчинский
31.03.13
✎
19:06
|
(8) для ТСД/смартфона фейс рисуешь..?
|
|||
19
Jolly Roger
31.03.13
✎
19:23
|
(0) мож лучше вебсервис и свой клиент?..
|
|||
20
Вуглускр1991
31.03.13
✎
20:54
|
(18) Да, у тебя же консультации брал.
Стиль окна менял, не меняется, можно только сделать его без THICK границы, то есть не изменяемым смысле высоты и ширины. Без SYSMENU не выходит. Кнопки никуда не пропадают. Можно выдавить его за экран, но тогда полоса от рабочего стола винды возникает внизу, а увеличение размера формы приводит только к скроллбарам. Окно рисуется по Y в координатах -30, но его нижняя граница не опускается ниже 290. Кнопки из титула тоже выдернуть не удается. Я перенумеровал все окна структура вот: (V8TopLevelFrameSDIsec, Заголовок формы , 0, 1) (V8LayouterTabsWindow, , 1, 2) (V8FormElement, , 2, 3) (V8LayouterTabsWindow, , 3, 4) (V8FormElement, , 4, 5) (V8Grid, , 5, 6) (V8FormElement, , 5, 7) (V8FormElement, , 5, 8) (V8LayouterTabsWindow, , 3, 10) (V8FormElement, , 4, 11) (V8LayouterTabsWindow, , 5, 12) (V8FormElement, , 6, 13) (V8FormElement, , 7, 14) (Shell Embedding, , 8, 15) (Shell DocObject View, , 9, 16) (V8FormElement, , 7, 17) (V8CommandBar, , 8, 18) (V8FormElement, , 7, 19) (V8FormElement, , 7, 20) (V8FormElement, , 7, 21) (V8FormElement, , 5, 22) (V8FormElement, , 3, 23) (V8FormElement, , 3, 24) (V8ViewSplitter, , 1, 25) (V8ViewSplitter, , 1, 26) (V8ViewSplitter, , 1, 27) (V8ViewSplitter, , 1, 28) (V8AutoHideLayouter, , 1, 29) (V8AutoHideLayouter, , 1, 30) (V8AutoHideLayouter, , 1, 31) (V8AutoHideLayouter, , 1, 32) (V8CommandBar, , 1, 33) (V8CommandBar, , 1, 34) (V8CommandBar, , 1, 35) (V8CommandBar, , 1, 36) (V8Dockbar, , 1, 37) (V8Dockbar, , 1, 38) (V8Dockbar, , 1, 39) (V8CommandBarDockFrame, , 2, 40) (V8CommandBar, , 3, 41) (V8CommandBarDockFrame, , 2, 42) (V8CommandBar, , 3, 43) (V8CommandBarDockFrame, , 2, 44) (V8CommandBar, , 3, 45) (V8CommandBarDockFrame, , 2, 46) (V8CommandBar, , 3, 47) (V8Dockbar, , 1, 48) (V8CommandBarDockFrame, , 2, 49) (V8CommandBar, , 3, 50) (V8CommandBarDockFrame, , 2, 51) (V8CommandBar, , 3, 52) (V8CommandBarDockFrame, , 2, 53) (V8CommandBar, , 3, 54) (V8CommandBarDockFrame, , 2, 55) (V8CommandBar, , 3, 56) (V8CommandBarDockFrame, , 2, 57) (V8CommandBar, , 3, 58) (V8CommandBarDockFrame, , 2, 59) (V8CommandBar, , 3, 60) (V8CommandBarDockFrame, , 2, 61) (V8CommandBar, , 3, 62) (V8CommandBar, , 1, 63) (V8FormElement, , 2, 64) Имя класса, имя окна, уровень вложенности и номер по порядку. Так вот, шняга с кнопками в титуле Это структура с номерами 63,64 а слать мышинные события для скорллбара надо в 13 (6-ой уровень). |
|||
21
Вуглускр1991
31.03.13
✎
21:20
|
(19) А сканер в ТСД?
|
|||
22
Вуглускр1991
31.03.13
✎
23:56
|
Итак: борзеем!
Из HWND №64 убираем стиль WS_VISIBLE, а HWND №2 перерисовываем в координатах 0,0,200,320 (разрешение ТСД 320x200) исчезает заголовок окна с батонами MAXIMIZE и CLOSE больше полезного места на форме. Добавляем на форму элемент управления средствами 1С. HWND №2 принимает свой первоначальный размер (почти все, кроме title c sysmenu) а место заголовка ничем не перерисовывается (остается грязным), но я смогу перерисовывать форму всякий раз после добавления элементов управления, используя внешнюю компоненту. |
Форум | Правила | Описание | Объявления | Секции | Поиск | Книга знаний | Вики-миста |