BG Development


Страници: (2) [1] 2   ( Първото ново мнение ) Reply to this topicStart new topicStart Poll

> Разпознаване на активния таб
FidelDahan
Публикувано на: 01-10-2013, 08:00
Quote Post



Име:
Група: Потребител
Ранг: Почетен член

Мнения: 2429
Регистриран на: 12.06.08



Правя един Add-In за Lync, където потребителя може от чат-прозорчето да натисне моето допълнително меню и да се изпълни моята програма (.NET .exe). За чата Lync използва табове, подобно на по-новите Internet Explorer, като един основен панел държи табовете, но долу в таскбара те се виждат като отделни прозорци. Проблема е, че Lync не ми дава контекст във кой от табовете потребителя е цъкнал, а трябва да го знам, за да мога да прочета контактите с които в момента чати.

B C# чрез Lync API мога да прочета всички чат-сесии и за всяка от тях да взема съответния ConversationWindow. Този ConversationWindow има един Handle, който е от тип IntPtr и предполагам че това е някакъв идентификатор за native прозореца или таба на съответния ConversationWindow. От друга страна мога също да намеря процеса lync.exe, към който пренадлежат всичките табове. Процеса от своя страна има един MainWindowHandle (пак IntPtr), но той съвпада със Handle само на първия ConversationWindow, а не на активния ConversationWindow. Даже понякога когато в чата има повече от двама участника MainWindowHandle не съвпада с никой Handle.

И сега се опитвам да разбера как да се докопам до активния таб и до неговия Handle, така че да го сравня със наличните ConversationWindow. Опитах с GetForegroundWindow() от user32.dll, но ми се струва че това ми дава process id на целия процес lync.exe (това получавам с Process.GetProcessById(handle)). Имате ли някакви идеи как да идентифицирам активния таб? Може би трябва да използвам тези функции?
http://msdn.microsoft.com/en-us/library/wi...9(v=vs.85).aspx
PMEmail Poster
Top
dvader
Публикувано на: 01-10-2013, 08:14
Quote Post


Group Icon
Име: Валерий Тодоров
Група: VIP
Ранг: Почетен член

Мнения: 5419
Регистриран на: 12.07.05



GetForegroundWindow() връща HWND...
Погледни GetGUIThreadInfo()

Прочее, нямаш гаранция, че идентификатора на активния прозорец ще съвпада с този на ConversationWindow. Първо, никъде не е казано, че ConversationWindow е HWND и второ, нищо не пречи единия прозорец да е вложен в другия.

Дали в това API няма нещо от типа на GetActiveSession или нещо подобно?

Това мнение е било редактирано от dvader на 01-10-2013, 08:19


--------------------
I find your lack of faith disturbing
PM
Top
FidelDahan
Публикувано на: 01-10-2013, 10:16
Quote Post



Име:
Група: Потребител
Ранг: Почетен член

Мнения: 2429
Регистриран на: 12.06.08



Няма никакъв начин да се открие активната чат сесия през нормалното API, това е проблема. 2 дни търсих защото не ми се вкарваха такива хакове, но без успех...

Какво е това HWND като концепт? ConversationWindow е обект от Lync API и той има едно поле Handle от тип IntPtr, което се надявам да съвпада с нещо което мога да получа от тези системни функции..

Благодаря за идеята с GetGUIThreadInfo()! От документацията не ми стана много ясно, как трябва да извикам тази функция? Т.е. от къде да взема този параметър idThread и как да задам lpgui?

UPDATE: ок, открих какво е HWND и как да използвам GetGUIThreadInfo(), само че ми дава резултат който не ми помага.

Имам процес lync.exe с 3 ConversationWindow таба:
* process.MainWindowHandle: 460500
* cw0.Handle: 460500
* cw1.Handle: 1049446 // това е активния таб на потребителя
* cw2.Handle: 1311404

Ето така се опитвам да намеря активния таб:

CODE
                   var conversationWindows = lyncClient.ConversationManager.Conversations.Select(c =>
                                             LyncClient.GetAutomation().GetConversationWindow(c));

                   Thread.Sleep(2000);
                   var activeHandle = GetCurrentTabHandle();
                   var activeWindow = conversationWindows.Single(cw => cw.Handle == activeHandle);


CODE
       [DllImport("user32.dll")]
       public static extern IntPtr GetForegroundWindow();

       [DllImport("user32.dll", SetLastError = true)]
       public static extern bool GetGUIThreadInfo(uint hTreadID, ref GUITHREADINFO lpgui);

       [DllImport("user32.dll")]
       public static extern uint GetWindowThreadProcessId(uint hwnd, out uint lpdwProcessId);

       [StructLayout(LayoutKind.Sequential)]
       public struct RECT
       {
           public int iLeft;
           public int iTop;
           public int iRight;
           public int iBottom;
       }

       [StructLayout(LayoutKind.Sequential)]
       public struct GUITHREADINFO
       {
           public int cbSize;
           public int flags;
           public int hwndActive;
           public int hwndFocus;
           public int hwndCapture;
           public int hwndMenuOwner;
           public int hwndMoveSize;
           public int hwndCaret;
           public RECT rectCaret;
       }

       public static IntPtr GetCurrentTabHandle()
       {
           //var clientProcess = Process.GetProcessesByName("lync").Single();
           //var hwnd = (uint)clientProcess.MainWindowHandle;
           
           //uint lpdwProcessId;
           //uint threadId = GetWindowThreadProcessId(hwnd, out lpdwProcessId);
           
           uint threadId = 0;

           GUITHREADINFO lpgui = new GUITHREADINFO();
           lpgui.cbSize = Marshal.SizeOf(lpgui);

           if (GetGUIThreadInfo(threadId, ref lpgui))
           {
               return new IntPtr(lpgui.hwndFocus);
           }
           else
           {
               // TODO: error handling, see SetLastError
               return IntPtr.Zero;
           }
       }


Като резултат от GetGUIThreadInfo получавам инициализиран struct GUITHREADINFO:
* hwndActive: 460500
* hwndFocus: 526052

Сега този hwndFocus има стойност която я няма в нито един от трите ConversationWindow.Handle. Това ме кара да мисля че този hwndFocus е handle на прозорец който е вграден в друг прозорец или нещо от този род. Някакво индиректно ниво, което не мога да разпозная.

Някакви идеи какво се случва?

Това мнение е било редактирано от FidelDahan на 01-10-2013, 13:03
PMEmail Poster
Top
wqw
Публикувано на: 01-10-2013, 16:22
Quote Post


Group Icon
Име: Владимир Висулчев
Група: VIP
Ранг: Почетен член

Мнения: 6379
Регистриран на: 10.06.04



Тествай фокусирания дали е IsChild на някой от табовете ти. Но така със сигурност ще стане мърляво at best.

Не можеш да тестваш за визибилити на hWnd на табовете? Ако даден таб ти е активен останалите не са ли скрити?

cheers,
</wqw>


--------------------
PMEmail PosterUsers Website
Top
ici
Публикувано на: 01-10-2013, 17:50
Quote Post


Group Icon
Име: Ивайло Илчев
Група: VIP
Ранг: Почетен член

Мнения: 19077
Регистриран на: 06.06.04



Дали не можеш да се закачиш и да дебнеш фокуса? http://msdn.microsoft.com/en-us/library/sy...enthandler.aspx


--------------------
Facebook is a bit like checking your underwear after a fart.
Most likely there's nothing new and if there is it's probably shit.
PMEmail PosterUsers Website
Top
JanBirdX
Публикувано на: 01-10-2013, 17:52
Quote Post



Име:
Група: Потребител
Ранг: Почетен член

Мнения: 1818
Регистриран на: 21.02.05



IntPtr е точно манипулатора на прозореца (HWND). Към студиото има една малка помощна програма Spy++ използвай е ако вече не си го направил.
PMEmail Poster
Top
dvader
Публикувано на: 02-10-2013, 07:19
Quote Post


Group Icon
Име: Валерий Тодоров
Група: VIP
Ранг: Почетен член

Мнения: 5419
Регистриран на: 12.07.05



Като се замисля, не може ли просто да прегледаш списъка на прозорците на процеса и да видиш кой е активния?


--------------------
I find your lack of faith disturbing
PM
Top
FidelDahan
Публикувано на: 02-10-2013, 14:16
Quote Post



Име:
Група: Потребител
Ранг: Почетен член

Мнения: 2429
Регистриран на: 12.06.08



@wqw, Пробвах с GetParent(), GetChildAtPoint() и прочие, но тези моите hWnd от списъка не се откриват. Таба може да е в този таб-панел, но може и да е изкаран (Un-Docked). Когато таба е изкаран от таб-панела неговия hWnd съответства на GUITHREADINFO.hwndActive, но когато е вътре при другите табове функцията ми не-винаги открива правинлия таб (понякога го обърква с първия таб в таб-панела). За жалост не е 100% надеждно и трябва да потърся нещо друго.

@ici, За фокуса не мога да се закача, защото е твърде късно, моята програма стартира като процес след като потребителя отвори таба в Lync и цъкне на едно custom menu, (което се регистрира през windows registry).

@JanBirdX, не го знаех това, ще го пробвам.

@dvader, идея е но дали няма да има същите проблеми както с GUITHREADINFO.hwndActive...

Почвам да мисля че като цяло подхода е грешен и трябва да се опита нещо по-стабилно... Благодаря на всички за помощтта!!!

Прикачена картинка (Кликнете на картинката, за да я увеличите!)
Прикачена картинка
PMEmail Poster
Top
ici
Публикувано на: 02-10-2013, 14:20
Quote Post


Group Icon
Име: Ивайло Илчев
Група: VIP
Ранг: Почетен член

Мнения: 19077
Регистриран на: 06.06.04



За Automation никога не е късно! icon_idea.gif


--------------------
Facebook is a bit like checking your underwear after a fart.
Most likely there's nothing new and if there is it's probably shit.
PMEmail PosterUsers Website
Top
FidelDahan
Публикувано на: 02-10-2013, 15:38
Quote Post



Име:
Група: Потребител
Ранг: Почетен член

Мнения: 2429
Регистриран на: 12.06.08



Това UI Automation си го представям че с него мога да контролирам прозорци програматично, да слушам за event-и етц, нали?

Проблема е, че моята програма се изпълнява чак накрая. Първо потребителя стартира своя Lync клиент и отваря чат сесии и чати тук там. После решава докато е в някой от тези табове да цъкне на едно допълнително меню долу вдясно в трите точки, което е там автоматично, без още моята програма да е стартирала като процес. От клика върху това меню Lync клиента извиква моята програма и и предава параметри като args. Т.е. моята програма не върви като нормален plugin вътре в процеса на Lync, а е отделен процес, който се задейства от този клик (това е by design от Lync, няма plugin-API). Чак тогава мога да направя нещо с Automation, но в този момент event-а който е бил за смяната на фокуса вече е минал...
PMEmail Poster
Top
0 потребители преглеждат тази тема в момента (0 гости, 0 анонимни потребители)
Потребители, преглеждащи темата в момента:

Topic Options Страници: (2) [1] 2  Reply to this topicStart new topicStart Poll

 


Copyright © 2003-2019 | BG Development | All Rights Reserved
RSS 2.0