Имя: Пароль:
1C
1С v8
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) а место заголовка ничем не перерисовывается (остается грязным),
но я смогу перерисовывать форму всякий раз после добавления элементов управления, используя внешнюю компоненту.
Чтобы обнаруживать ошибки, программист должен иметь ум, которому доставляет удовольствие находить изъяны там, где, казалось, царят красота и совершенство. Фредерик Брукс-младший