/[rdesktop]/sourceforge.net/trunk/seamlessrdp/ClientDLL/clipper.cpp
This is repository of my old source code which isn't updated any more. Go to git.rot13.org for current projects!
ViewVC logotype

Annotation of /sourceforge.net/trunk/seamlessrdp/ClientDLL/clipper.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 930 - (hide annotations)
Thu Jun 30 14:14:56 2005 UTC (19 years ago) by astrand
File size: 14866 byte(s)
Should have UNIX LF linebreaks, when running CVS from UNIX.

1 astrand 930 //*********************************************************************************
2     //
3     //Title: Terminal Services Window Clipper
4     //
5     //Author: Martin Wickett
6     //
7     //Date: 2004
8     //
9     //*********************************************************************************
10    
11     #define TSDLL
12    
13     #include "clipper.h"
14    
15     BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
16     {
17     UNREFERENCED_PARAMETER(lpvReserved);
18     UNREFERENCED_PARAMETER(hinstDLL);
19    
20     switch(fdwReason)
21     {
22     case DLL_PROCESS_ATTACH:
23     break;
24    
25     case DLL_THREAD_ATTACH:
26     break;
27    
28     case DLL_THREAD_DETACH:
29     break;
30    
31     case DLL_PROCESS_DETACH:
32     break;
33    
34     default:
35     break;
36     }
37     return TRUE;
38     }
39    
40     void WINAPI VirtualChannelOpenEvent(DWORD openHandle, UINT event, LPVOID pdata,
41     UINT32 dataLength, UINT32 totalLength, UINT32 dataFlags)
42     {
43     LPDWORD pdwControlCode = (LPDWORD)pdata;
44     CHAR ourData[1600];
45     UINT ui = 0;
46    
47     UNREFERENCED_PARAMETER(openHandle);
48     UNREFERENCED_PARAMETER(dataFlags);
49    
50     ZeroMemory(ourData, sizeof(ourData));
51    
52     //copy the send string (with the same lenth of the data)
53     strncpy(ourData,(LPSTR)pdata,dataLength/sizeof(char));
54    
55     if (OUTPUT_DEBUG_INFO == 1 )
56     {
57     OutputDebugString("TS WINDOW CLIPPER :: CLIENT DLL :: Info --> Virtual channel data received");
58     OutputDebugString(ourData);
59     }
60    
61     if (dataLength == totalLength)
62     {
63     switch(event)
64     {
65     case CHANNEL_EVENT_DATA_RECEIVED:
66     {
67     CTokenizer tok(_T((LPSTR)ourData), _T(";"));
68     CStdString cs;
69    
70     CWindowData* wid=new CWindowData("");
71     CStdString messageType;
72     int mixMaxType = 0;
73    
74     while(tok.Next(cs))
75     {
76     CStdString msg;
77     CTokenizer msgTok(cs, _T("="));
78    
79     msgTok.Next(msg);
80    
81     if (strcmp(msg,"MSG")==0)
82     {
83     msgTok.Next(msg);
84     messageType = msg;
85     }
86    
87     if (strcmp(msg,"ID")==0)
88     {
89     msgTok.Next(msg);
90     wid->SetId(msg);
91     }
92     else if (strcmp(msg,"TITLE")==0)
93     {
94     msgTok.Next(msg);
95     wid->SetTitle(msg);
96     }
97     else if (strcmp(msg,"POS")==0)
98     {
99     msgTok.Next(msg);
100    
101     CStdString pos;
102     CTokenizer posTok(msg, _T("~"));
103    
104     posTok.Next(pos);
105    
106    
107     // check bounds, coords can be negative if window top left point is moved off the screen.
108     // we don't care about that since the window can't be see so just use zero.
109    
110     if (strchr(pos, '-')==NULL)
111     {
112     wid->SetX1(atoi(pos));
113     }
114     else
115     {
116     wid->SetX1(0);
117     }
118    
119     posTok.Next(pos);
120    
121     if (strchr(pos, '-')==NULL)
122     {
123     wid->SetY1(atoi(pos));
124     }
125     else
126     {
127     wid->SetY1(0);
128     }
129    
130     posTok.Next(pos);
131    
132     if (strchr(pos, '-')==NULL)
133     {
134     wid->SetX2(atoi(pos));
135     }
136     else
137     {
138     wid->SetX2(0);
139     }
140    
141     posTok.Next(pos);
142    
143     if (strchr(pos, '-')==NULL)
144     {
145     wid->SetY2(atoi(pos));
146     }
147     else
148     {
149     wid->SetY2(0);
150     }
151     }
152     else if (strcmp(msg,"TYPE")==0)
153     {
154     msgTok.Next(msg);
155     mixMaxType = atoi(msg);
156     }
157     }
158    
159     if (strcmp(messageType,"HSHELL_WINDOWCREATED")==0)
160     {
161     if (OUTPUT_DEBUG_INFO == 1 )
162     {
163     OutputDebugString("TS WINDOW CLIPPER :: CLIENT DLL :: Info --> Message was of type HSHELL_WINDOWCREATED window title is:");
164     OutputDebugString(wid->GetTitle());
165     }
166    
167     CStdString s = wid->GetId();
168     char *ptr;
169     int length = s.GetLength();
170     ptr = s.GetBufferSetLength(length);
171    
172     hash_insert(ptr,wid,&m_ht);
173    
174     CreateAndShowWindow(wid);
175    
176     DoClipping(1);
177     }
178     else if(strcmp(messageType,"HSHELL_WINDOWDESTROYED")==0)
179     {
180     if (OUTPUT_DEBUG_INFO == 1 )
181     {
182     OutputDebugString("TS WINDOW CLIPPER :: CLIENT DLL :: Info --> Message was of type HSHELL_WINDOWDISTROYED window title is:");
183     OutputDebugString(wid->GetTitle());
184     }
185    
186     CStdString s = wid->GetId();
187     char *ptr;
188     int length = s.GetLength();
189     ptr = s.GetBufferSetLength(length);
190    
191     CWindowData* oldWinData = (CWindowData*) hash_del(ptr,&m_ht);
192    
193     DestroyTaskbarWindow(oldWinData);
194    
195     delete oldWinData;
196    
197     DoClipping(1);
198     }
199     else if(strcmp(messageType,"HCBT_MINMAX")==0)
200     {
201     if (OUTPUT_DEBUG_INFO == 1 )
202     {
203     OutputDebugString("TS WINDOW CLIPPER :: CLIENT DLL :: Info --> Message was of type HCBT_MINMAX");
204     }
205    
206    
207     //TODO
208    
209     }
210     else if(strcmp(messageType,"HCBT_MOVESIZE")==0)
211     {
212     if (OUTPUT_DEBUG_INFO == 1 )
213     {
214     OutputDebugString("TS WINDOW CLIPPER :: CLIENT DLL :: Info --> Message was of type HCBT_MOVESIZE window title is:");
215     OutputDebugString(wid->GetTitle());
216     }
217    
218     CStdString s = wid->GetId();
219     char *ptr;
220     int length = s.GetLength();
221     ptr = s.GetBufferSetLength(length);
222    
223     CWindowData* movedWinData = (CWindowData*) hash_lookup(ptr,&m_ht);
224    
225     if(movedWinData!=NULL)
226     {
227     movedWinData->SetX1(wid->GetX1());
228     movedWinData->SetX2(wid->GetX2());
229     movedWinData->SetY1(wid->GetY1());
230     movedWinData->SetY2(wid->GetY2());
231    
232     DoClipping(1);
233     }
234    
235     delete wid;
236     }
237     else if(strcmp(messageType,"CALLWNDPROC_WM_MOVING")==0)
238     {
239     if (OUTPUT_DEBUG_INFO == 1 )
240     {
241     OutputDebugString("TS WINDOW CLIPPER :: CLIENT DLL :: Info --> Message was of type CALLWNDPROC_WM_MOVING window title is:");
242     OutputDebugString(wid->GetTitle());
243     }
244    
245     CStdString s = wid->GetId();
246     char *ptr;
247     int length = s.GetLength();
248     ptr = s.GetBufferSetLength(length);
249    
250     CWindowData* movedWinData = (CWindowData*) hash_lookup(ptr,&m_ht);
251    
252     if(movedWinData!=NULL)
253     {
254     movedWinData->SetX1(wid->GetX1());
255     movedWinData->SetX2(wid->GetX2());
256     movedWinData->SetY1(wid->GetY1());
257     movedWinData->SetY2(wid->GetY2());
258    
259     ////might be too much of an overhead forcing the redraw here. Might be better to do 'DoClipping(0)' instead?
260     DoClipping(1);
261     }
262    
263     delete wid;
264     }
265     }
266     break;
267    
268     case CHANNEL_EVENT_WRITE_COMPLETE:
269     {
270     }
271     break;
272    
273     case CHANNEL_EVENT_WRITE_CANCELLED:
274     {
275     }
276     break;
277    
278     default:
279     {
280     }
281     break;
282     }
283     }
284     else
285     {
286     }
287     }
288    
289    
290     VOID VCAPITYPE VirtualChannelInitEventProc(LPVOID pInitHandle, UINT event, LPVOID pData, UINT dataLength)
291     {
292     UINT ui;
293    
294     UNREFERENCED_PARAMETER(pInitHandle);
295     UNREFERENCED_PARAMETER(dataLength);
296    
297     switch(event)
298     {
299     case CHANNEL_EVENT_INITIALIZED:
300     {
301     }
302     break;
303    
304     case CHANNEL_EVENT_CONNECTED:
305     {
306     //
307     // open channel
308     //
309     ui = gpEntryPoints->pVirtualChannelOpen(gphChannel,&gdwOpenChannel,CHANNELNAME,(PCHANNEL_OPEN_EVENT_FN)VirtualChannelOpenEvent);
310    
311     if (ui == CHANNEL_RC_OK)
312     {
313    
314     }
315     else
316     {
317     MessageBox(NULL,TEXT("Open of RDP virtual channel failed"),TEXT("TS Window Clipper"),MB_OK);
318     }
319    
320     if (ui != CHANNEL_RC_OK)
321     {
322     return;
323     }
324     }
325     break;
326    
327     case CHANNEL_EVENT_V1_CONNECTED:
328     {
329     MessageBox(NULL,TEXT("Connecting to a non Windows 2000 Terminal Server"),TEXT("TS Window Clipper"),MB_OK);
330     }
331     break;
332    
333     case CHANNEL_EVENT_DISCONNECTED:
334     {
335    
336     }
337     break;
338    
339     case CHANNEL_EVENT_TERMINATED:
340     {
341     //
342     // free the entry points table
343     //
344     LocalFree((HLOCAL)gpEntryPoints);
345     }
346     break;
347    
348     default:
349     {
350    
351     }
352     break;
353     }
354     }
355    
356     BOOL VCAPITYPE VirtualChannelEntry(PCHANNEL_ENTRY_POINTS pEntryPoints)
357     {
358     CHANNEL_DEF cd;
359     UINT uRet;
360    
361     size_t s = 10;
362     hash_construct_table(&m_ht, s);
363    
364     //
365     // allocate memory
366     //
367     gpEntryPoints = (PCHANNEL_ENTRY_POINTS) LocalAlloc(LPTR, pEntryPoints->cbSize);
368    
369     memcpy(gpEntryPoints, pEntryPoints, pEntryPoints->cbSize);
370    
371     //
372     // initialize CHANNEL_DEF structure
373     //
374     ZeroMemory(&cd, sizeof(CHANNEL_DEF));
375     strcpy(cd.name, CHANNELNAME); // ANSI ONLY
376    
377     //
378     // register channel
379     //
380     uRet = gpEntryPoints->pVirtualChannelInit((LPVOID *)&gphChannel,(PCHANNEL_DEF)&cd, 1,VIRTUAL_CHANNEL_VERSION_WIN2000,(PCHANNEL_INIT_EVENT_FN)VirtualChannelInitEventProc);
381    
382     if (uRet == CHANNEL_RC_OK)
383     {
384     if (ALWAYS__CLIP)
385     {
386     DoClipping(1);
387     }
388     }
389     else
390     {
391     MessageBox(NULL,TEXT("RDP Virtual channel Init Failed"),TEXT("TS Window Clipper"),MB_OK);
392     }
393    
394     if (uRet != CHANNEL_RC_OK)
395     {
396     return FALSE;
397     }
398    
399     //
400     // make sure channel was initialized
401     //
402     if (cd.options != CHANNEL_OPTION_INITIALIZED)
403     {
404     return FALSE;
405     }
406    
407     return TRUE;
408     }
409    
410    
411     // data structure to transfer informations
412     typedef struct _WindowFromProcessOrThreadID
413     {
414     union
415     {
416     DWORD procId;
417     DWORD threadId;
418     };
419     HWND hWnd;
420     }Wnd4PTID;
421    
422     // Callback procedure
423     BOOL CALLBACK PrivateEnumWindowsProc(HWND hwnd,LPARAM lParam)
424     {
425     DWORD procId;
426     DWORD threadId;
427     Wnd4PTID* tmp = (Wnd4PTID*)lParam;
428     // get the process/thread id of current window
429     threadId = GetWindowThreadProcessId(hwnd, &procId);
430     // check if the process/thread id equal to the one passed by lParam?
431     if(threadId == tmp->threadId || procId == tmp->procId)
432     {
433     // check if the window is a main window
434     // because there lots of windows belong to the same process/thread
435     LONG dwStyle = GetWindowLong(hwnd, GWL_STYLE);
436     if(dwStyle & WS_SYSMENU)
437     {
438     tmp->hWnd = hwnd;
439     return FALSE; // break the enumeration
440     }
441     }
442     return TRUE; // continue the enumeration
443     }
444    
445     // Enumarate all the MainWindow of the system
446     HWND FindProcessMainWindow(DWORD procId)
447     {
448     Wnd4PTID tempWnd4ID;
449     tempWnd4ID.procId = procId;
450     if(!EnumWindows((WNDENUMPROC)PrivateEnumWindowsProc, (LPARAM)&tempWnd4ID))
451     {
452    
453     if (OUTPUT_DEBUG_INFO == 1 )
454     {
455     OutputDebugString("TS WINDOW CLIPPER :: CLIENT DLL :: Info --> Found main process window");
456     }
457    
458     return tempWnd4ID.hWnd;
459     }
460    
461    
462     if (OUTPUT_DEBUG_INFO == 1 )
463     {
464     OutputDebugString("TS WINDOW CLIPPER :: CLIENT DLL :: Info --> Could not find main process window");
465     }
466    
467     return NULL;
468     }
469    
470    
471     void DoClipping(int forceRedraw)
472     {
473     //if main window handle is null, try to get it
474     if (m_mainWindowHandle==NULL)
475     {
476     m_mainWindowHandle = FindProcessMainWindow(GetCurrentProcessId());
477    
478     //hide the window from taskbar and put at the back of the z order
479     if ( HIDE_TSAC_WINDOW ==1 )
480     {
481     ShowWindow(m_mainWindowHandle, SW_HIDE);
482     SetWindowLongPtr(m_mainWindowHandle, GWL_EXSTYLE,GetWindowLong(m_mainWindowHandle, GWL_EXSTYLE) | WS_EX_TOOLWINDOW);
483     ShowWindow(m_mainWindowHandle, SW_SHOW);
484     }
485    
486     SetWindowPos(m_mainWindowHandle, HWND_NOTOPMOST, 0, 0, 0, 0,SWP_NOMOVE | SWP_NOSIZE);
487     }
488    
489     //if we have the handle, lets use it for the clipping
490     if (m_mainWindowHandle!=NULL)
491     {
492     RECT wRect;
493     GetWindowRect(m_mainWindowHandle,&wRect);
494    
495     if (OUTPUT_DEBUG_INFO == 1 )
496     {
497     OutputDebugString("TS WINDOW CLIPPER :: CLIENT DLL :: Info --> Restarting clipping...");
498     }
499    
500     m_regionResult = NULL;
501    
502     if (OUTPUT_WINDOW_TABLE_DEBUG_INFO == 1 )
503     {
504     OutputDebugString("-----------------------------------------------------------------------------");
505     OutputDebugString("TS WINDOW CLIPPER :: CLIENT DLL :: Info --> starting printing of window table");
506     }
507    
508     //enumerate though hashtable
509     if (&m_ht!=NULL)
510     {
511     hash_enumerate( &m_ht, CreateRegionFromWindowData);
512     }
513    
514     if (OUTPUT_WINDOW_TABLE_DEBUG_INFO == 1 )
515     {
516     OutputDebugString("TS WINDOW CLIPPER :: CLIENT DLL :: Info --> finished printing of window table");
517     OutputDebugString("-----------------------------------------------------------------------------");
518     }
519    
520     if (m_regionResult==NULL)
521     {
522     if (ALWAYS__CLIP)
523     {
524     m_regionResult=CreateRectRgn(0,0,0,0);
525     }
526     else
527     {
528     m_regionResult = CreateRectRgn(0,0,wRect.right,wRect.bottom);
529     }
530     }
531    
532     SetWindowRgn(m_mainWindowHandle,(HRGN__*)m_regionResult, TRUE);
533    
534     if (forceRedraw==1)
535     {
536     // invalidate the window and force it to redraw
537     RedrawWindow(m_mainWindowHandle,NULL,NULL, RDW_INVALIDATE | RDW_UPDATENOW | RDW_ALLCHILDREN);
538     }
539     }
540     else
541     {
542     if (OUTPUT_DEBUG_INFO == 1 )
543     {
544     OutputDebugString("TS WINDOW CLIPPER :: CLIENT DLL :: Info --> Coulf not find window to clip");
545     }
546     }
547     }
548    
549     void CreateRegionFromWindowData(char * key,void * value)
550     {
551     CWindowData* wd;
552     wd = (CWindowData*)value;
553     int x1=0,x2=0,y1=0,y2=0;
554    
555     char strB[5];
556     char strT[5];
557     char strL[5];
558     char strR[5];
559    
560     if (m_regionResult==NULL)
561     {
562     m_regionResult=CreateRectRgn(0,0,0,0);
563     }
564    
565     if (OUTPUT_DEBUG_INFO == 1 && OUTPUT_WINDOW_TABLE_DEBUG_INFO != 1)
566     {
567     OutputDebugString("TS WINDOW CLIPPER :: CLIENT DLL :: Info --> Adding this window to cliping region");
568     OutputDebugString(wd->GetTitle());
569     }
570     if (OUTPUT_WINDOW_TABLE_DEBUG_INFO == 1 )
571     {
572     ltoa(wd->GetY2(),strB,10);
573     ltoa(wd->GetY1(),strT,10);
574     ltoa(wd->GetX2(),strR,10);
575     ltoa(wd->GetX1(),strL,10);
576    
577     OutputDebugString("This window is in the table:");
578     OutputDebugString(wd->GetTitle());
579     OutputDebugString(wd->GetId());
580     OutputDebugString(strL);
581     OutputDebugString(strT);
582     OutputDebugString(strR);
583     OutputDebugString(strB);
584     OutputDebugString("*******************");
585     }
586    
587     HRGN newRegion = CreateRectRgn(wd->GetX1(),wd->GetY1(),wd->GetX2(),wd->GetY2());
588    
589     CombineRgn(m_regionResult, newRegion, m_regionResult, RGN_OR);
590     }
591    
592     /*
593     Dummy procedure to catch when window is being maximised.
594    
595     Need to tell the window on the server to do the same.
596     */
597     LRESULT CALLBACK DummyWindowCallbackProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
598     {
599     //TODO
600    
601     return DefWindowProc(hwnd, uMsg, wParam, lParam);
602     }
603    
604     void CreateAndShowWindow(CWindowData* wd)
605     {
606     if (classAlreadyRegistered==0)
607     {
608     static const char *szWndName = "WTSWinClipperDummy";
609     WNDCLASS wc;
610    
611     wc.style = 0;
612     wc.lpfnWndProc = DummyWindowCallbackProc;
613     wc.cbClsExtra = 0;
614     wc.cbWndExtra = 0;
615     wc.hInstance = 0;
616     wc.hIcon = 0;
617     wc.hCursor = 0;
618     wc.hbrBackground = 0;
619     wc.lpszMenuName = 0;
620     wc.lpszClassName = szWndName;
621    
622     if (RegisterClass(&wc))
623     {
624     classAlreadyRegistered=1;
625     }
626     }
627    
628     if (classAlreadyRegistered=1)
629     {
630     HWND hWnd = CreateWindow(TEXT("WTSWinClipperDummy"), wd->GetTitle(), WS_POPUP, 0, 0, 0, 0, 0, 0, 0, 0);
631     ShowWindow( hWnd, 3 );
632     SetWindowPos(hWnd,0,0,0,0,0,SWP_NOREDRAW);
633     wd->TaskbarWindowHandle = hWnd;
634     SetFocus(m_mainWindowHandle);
635     }
636     }
637    
638     void DestroyTaskbarWindow(CWindowData* wd)
639     {
640     if (wd->TaskbarWindowHandle != NULL)
641     {
642     DestroyWindow(wd->TaskbarWindowHandle);
643     }
644 astrand 918 }

  ViewVC Help
Powered by ViewVC 1.1.26