library AstonAltDesk; uses Windows, Messages, // SysUtils, FNxxx in '..\..\FNxxx.pas', AstonSDK in '..\..\AstonSDK.pas', st_api in '..\..\st_api.pas'; //$IFDEF Debug} // $E .plg} //$ELSE} {$I ..\plg.pas} //$ENDIF} {$IMAGEBASE $00400000} const szName:Pchar = 'Aston+AltDesk 1.1'; szCaption:Pchar = 'Aston+AltDeskWin'; // szName:Pchar = 'AfxFrameOrView70'; // szCaption:Pchar = 'iTouchWin'; szHelp:PChar = 'Aston+AltDesk 1.1'#13#10+ 'Простой плагин для обьединения этих двух программ.'#13#10+ 'Для корректной работы требует запущенного AltDesk'#13#10+ 'Установите горячие клавиши на рабочих столах shift+alt+win+F1 для первого рабочего стола'#13#10+ ' shift+alt+win+F2 для второго рабочего стола'#13#10+ ' shift+alt+win+F3 для третьего рабочего стола'#13#10+ ' shift+alt+win+F4 для четвёртого рабочего стола.'#13#10+ ' на данный момент поддерживается максимум 12 рабочих столов.'#13#10+ 'Все ваши комментарии присылайте на admDenis@yandex.ru'#13#10+ ''#13#10+ 'Simple plug-in for joing AltDesk to Aston.'#13#10+ 'For correct work y0u should run AltDesk'#13#10+ 'Also y0u should setup hot-keys on virtual desktops,'#13#10+ 'shift+alt+win+F1 for the first virtual desktop.'#13#10+ 'shift+alt+win+F2 for second'#13#10+ 'and etc.'#13#10+ 'At that moment max. 12 virtualdesktops support.'#13#10+ ''#13#10+ 'All y0ur comment send to admDenis@yandex.ru'#13#10+ '29.09.2004 Константинов Денис (Konstantinov Denis)'#13#10+ 'HomePage http://admDenis.narod.ru'#13#10#13#10+ 'Special thanks to Veratil & Zealot-6'; szAutoHide = 'AutoHide'; szPos = 'Position'; cPosOptions = 1; vPosOptions:array[0..cPosOptions] of PChar=('Left(Top)','Right(Bottom)'); szPriority = 'Priority Position'; szTimeToHide ='TimeToHide'; szNumOfDeskTops = 'NumOfDeskTops'; szSkinPath = 'SkinPath'; szShowOnMouseOver = 'Show AltDesk OnMouseOver'; szClickOptions = 'On Left mouse click'; cClickOptions = 2; vClickOptions:array[0..cClickOptions] of PChar=('Do Nothing','Show AltDesk','Switch to hand-picked desktop'); szDeskIco = 'Width of Desktop icon'; szShowNum = 'Show Desktop Numbers'; szColor = 'Numbers Color'; szFont = 'Numbers Font'; KeyCount = 12; Keys: array[1..KeyCount] of TKey = ( (szKey:szPos; nType:KEY_LIST or KEY_NOTHEME; szHint: szPos; vDefault: 0; res1:cPosOptions; res2:0), (szKey:szPriority; nType:KEY_INT or KEY_NOTHEME; szHint: szPriority; vDefault: 1; res1:0; res2:0), (szKey:szAutoHide; nType:KEY_BOOL or KEY_NOTHEME; szHint: szAutoHide; vDefault: 1; res1:0; res2:0), (szKey:szTimeToHide; nType:KEY_INT or KEY_NOTHEME; szHint: szTimeToHide; vDefault: 1000; res1:0; res2:0), (szKey:szNumOfDeskTops; nType:KEY_SCROLLBAR or KEY_NOTHEME; szHint: szNumOfDeskTops; vDefault: 4; res1:1; res2:12), (szKey:szSkinPath; nType:KEY_PATH; szHint: szSkinPath; vDefault: 0; res1:0; res2:0), (szKey:szShowOnMouseOver; nType:KEY_BOOL or KEY_NOTHEME; szHint: szShowOnMouseOver; vDefault: 1; res1:0; res2:0), (szKey:szClickOptions; nType:KEY_LIST or KEY_NOTHEME; szHint: szClickOptions; vDefault: 2; res1:cClickOptions; res2:0), (szKey:szDeskIco; nType:KEY_INT or KEY_NOTHEME; szHint: szDeskIco; vDefault: 20; res1:0; res2:0), (szKey:szShowNum; nType:KEY_BOOL or KEY_NOTHEME; szHint: szShowNum; vDefault: 1; res1:0; res2:0), (szKey:szColor; nType:KEY_COLOR; szHint: szColor; vDefault: $573f20; res1:0; res2:0), (szKey:szFont; nType:KEY_FONT; szHint: szFont; vDefault: 1; res1:0; res2:0) ); var AData: TAstonData; MyAutoHide:boolean=true; ChildWindow:hWnd=0; hWndAltDesk:HWND=0; hMessBut:HWND=0; TimeToHide:integer=1000; MyWidth:integer = 0; DeskIco:integer=20; RecAlt,RecMy:TRect; Position:integer=2; VPriority:integer=0; WeWork:boolean=false; TimerWork:boolean=false; bmp_Bk,bmp_BkAlt:TPicture; NumOfDeskTops:integer =4; ShowOnMouseOver:boolean = true; SkinPath:string; ClickOptions:integer=2; ShowNum:boolean=true; Color:COLORREF; Font:TFont; {----------------------------------------------------------------} PluginInfo:TPluginInfo; {----------------------------------------------------------------} function Int2Str(Number : Int64) : String; var Minus : Boolean; begin {SysUtils is not in the Uses Clause so I can not use IntToStr( ) and have to define an Int2Str( ) function here} Result := ''; if Number = 0 then Result := '0'; Minus := Number < 0; if Minus then Number := -Number; while Number > 0 do begin Result := Char((Number mod 10) + Integer('0')) + Result; Number := Number div 10; end; if Minus then Result := '-' + Result; end; function Str2Int(S:AnsiString): Int64; var Minus : Boolean; Step,N,i,j:integer; begin Minus:=false; Result := 0; N:=Length(S); for i:=1 to N do begin step:=1; if S[I]='-' then begin Minus:=true; Continue; end else if (Byte(S[I]) >47) and (Byte(S[I])<58) then begin for j:=1 to N-I do step:=step*10; Result :=Result+ (Byte(S[i])-48)*step; end; end; if Minus then Result :=Result*(-1); end; procedure SetKbdState(KeyCode: Byte); var KBState: TKeyboardState; osvi:OSVERSIONINFO; szVersion:array[0..80] of char; A_malloc:FARPROC; sez:Integer; begin osvi.dwOSVersionInfoSize := sizeof (OSVERSIONINFO); GetVersionEx (osvi); if (osvi.dwPlatformId = VER_PLATFORM_WIN32_NT) then begin keybd_event(VK_SHIFT, 1, 0, 0); keybd_event(VK_MENU, 1, 0, 0); keybd_event(VK_LWIN, 1, 0, 0); keybd_event(KeyCode, 1, 0, 0); keybd_event(KeyCode, 1, KEYEVENTF_KEYUP, 0); keybd_event(VK_SHIFT, 1, KEYEVENTF_KEYUP, 0); keybd_event(VK_MENU, 1, KEYEVENTF_KEYUP, 0); keybd_event(VK_LWIN, 1, KEYEVENTF_KEYUP, 0); end else begin GetKeyboardState(KBState); KBState[VK_SHIFT] := 1; KBState[VK_MENU] := 1; KBState[VK_LWIN] :=1; KBState[KeyCode] := 1; SetKeyboardState(KBState); KBState[VK_SHIFT] := 0; KBState[VK_MENU] := 0; KBState[VK_LWIN] :=0; KBState[KeyCode] := 0; SetKeyboardState(KBState); end; end; function FindAltDesk():boolean; begin result:=false; hWndAltDesk:=FindWindow('AltDesk1.x',nil); if hWndAltDesk>0 then result:=true; WeWork:=false; TimerWork:=false; KillTimer(ChildWindow,2); end; procedure SetPlace(); var wp2,wp:TRect; swp:WINDOWPLACEMENT; MyA,MyB,AltA,AltB,MyHeight,MyWidth,AltHeight,AltWidth,XSCREEN,YSCREEN:integer; s:string; begin if(GetWindowRect(hWndAltDesk,wp)=false) then if(not FindAltDesk()) then exit; //altDesk GetWindowRect(ChildWindow,wp2);//MyWindow GetWindowPlacement(hWndAltDesk,@swp); //s:=' mx='+IntToStr(wp2.Left)+' my='+IntToStr(wp2.Top)+' max='+IntToStr(wp2.Right)+' may='+IntToStr(wp2.Bottom); //MessageBox(ChildWindow,PChar(S),'Test',MB_OK); MyHeight:=wp2.Bottom-wp2.Top; MyWidth:=wp2.Right-wp2.Left; MyA:=wp2.Top+(MyHeight div 2); MyB:=wp2.Left+(MyWidth div 2); AltHeight:=wp.Bottom-wp.Top; AltWidth:=wp.Right-wp.Left; AltA:=wp.Top+(AltHeight div 2); AltB:=wp.Left+(AltWidth div 2); XSCREEN:=GetSystemMetrics(SM_CXSCREEN); //1024 YSCREEN:=GetSystemMetrics(SM_CYSCREEN); //768 if wp2.Left<5 then //Левый край begin //MessageBox(ChildWindow,'Левый','Test',MB_OK); if (MyA>(AltHeight div 2)) and (MyA<(YSCREEN-(AltHeight div 2))) then begin //MessageBox(ChildWindow,'Левый1','Test',MB_OK); swp.rcNormalPosition.Left:=wp2.Right; swp.rcNormalPosition.Right:=swp.rcNormalPosition.Left+AltWidth; swp.rcNormalPosition.Top:=MyA-(AltHeight div 2); swp.rcNormalPosition.Bottom:=swp.rcNormalPosition.Top+AltHeight; end else if (MyA<(AltHeight div 2)) then begin //MessageBox(ChildWindow,'Левый2','Test',MB_OK); swp.rcNormalPosition.Left:=wp2.Right; swp.rcNormalPosition.Right:=swp.rcNormalPosition.Left+AltWidth; swp.rcNormalPosition.Top:=MyA-(AltHeight div 2)+((AltHeight div 2)-MyA); swp.rcNormalPosition.Bottom:=swp.rcNormalPosition.Top+AltHeight; end else if (MyA>(YSCREEN-(AltHeight div 2))) then begin //MessageBox(ChildWindow,'Левый3','Test',MB_OK); swp.rcNormalPosition.Left:=wp2.Right; swp.rcNormalPosition.Right:=swp.rcNormalPosition.Left+AltWidth; swp.rcNormalPosition.Top:=MyA-(AltHeight div 2)-((AltHeight div 2)-(YSCREEN-MyA)); swp.rcNormalPosition.Bottom:=swp.rcNormalPosition.Top+AltHeight; end; end else if wp2.Top=0 then //Верх begin //MessageBox(ChildWindow,'Верх','Test',MB_OK); if (MyB>(AltWidth div 2)) and (MyB<(XSCREEN-(AltWidth div 2))) then begin //MessageBox(ChildWindow,'Верх1','Test',MB_OK); swp.rcNormalPosition.Left:=MyB-(AltWidth div 2); swp.rcNormalPosition.Right:=swp.rcNormalPosition.Left+AltWidth; swp.rcNormalPosition.Top:=wp2.Bottom; swp.rcNormalPosition.Bottom:=swp.rcNormalPosition.Top+AltHeight; end else if (MyB<(AltWidth div 2)) then begin //MessageBox(ChildWindow,'Верх2','Test',MB_OK); swp.rcNormalPosition.Left:=MyB-(AltWidth div 2)+((AltWidth div 2)-MyB); swp.rcNormalPosition.Right:=swp.rcNormalPosition.Left+AltWidth; swp.rcNormalPosition.Top:=wp2.Bottom; swp.rcNormalPosition.Bottom:=swp.rcNormalPosition.Top+AltHeight; end else if (MyB>(XSCREEN-(AltWidth div 2))) then begin //MessageBox(ChildWindow,'Верх3','Test',MB_OK); swp.rcNormalPosition.Left:=MyB-(AltWidth div 2)-((AltWidth div 2)-(XSCREEN-MyB)); swp.rcNormalPosition.Right:=swp.rcNormalPosition.Left+AltWidth; swp.rcNormalPosition.Top:=wp2.Bottom; swp.rcNormalPosition.Bottom:=swp.rcNormalPosition.Top+AltHeight; end; end else if (wp2.Right>(XSCREEN-5)) then //Правый край begin //MessageBox(ChildWindow,'Правый','Test',MB_OK); if (MyA>(AltHeight div 2)) and (MyA<(YSCREEN-(AltHeight div 2))) then begin //MessageBox(ChildWindow,'Правый1','Test',MB_OK); swp.rcNormalPosition.Right:=wp2.left; swp.rcNormalPosition.Left:=swp.rcNormalPosition.Right-AltWidth; swp.rcNormalPosition.Top:=MyA-(AltHeight div 2); swp.rcNormalPosition.Bottom:=swp.rcNormalPosition.Top+AltHeight; end else if (MyA<(AltHeight div 2)) then begin //MessageBox(ChildWindow,'Правый2','Test',MB_OK); swp.rcNormalPosition.Right:=wp2.left; swp.rcNormalPosition.Left:=swp.rcNormalPosition.Right-AltWidth; swp.rcNormalPosition.Top:=MyA-(AltHeight div 2)+((AltHeight div 2)-MyA); swp.rcNormalPosition.Bottom:=swp.rcNormalPosition.Top+AltHeight; end else if (MyA>(YSCREEN-(AltHeight div 2))) then begin //MessageBox(ChildWindow,'Правый3','Test',MB_OK); swp.rcNormalPosition.Right:=wp2.left; swp.rcNormalPosition.Left:=swp.rcNormalPosition.Right-AltWidth; swp.rcNormalPosition.Top:=MyA-(AltHeight div 2)-((AltHeight div 2)-(YSCREEN-MyA)); swp.rcNormalPosition.Bottom:=swp.rcNormalPosition.Top+AltHeight; end; end else if wp2.Bottom=YSCREEN then //Низ begin //MessageBox(ChildWindow,'Низ','Test',MB_OK); if (MyB>(AltWidth div 2)) and (MyB<(XSCREEN-(AltWidth div 2))) then begin //MessageBox(ChildWindow,'Низ1','Test',MB_OK); swp.rcNormalPosition.Left:=MyB-(AltWidth div 2); swp.rcNormalPosition.Right:=swp.rcNormalPosition.Left+AltWidth; swp.rcNormalPosition.Bottom:=wp2.Top; swp.rcNormalPosition.Top:=swp.rcNormalPosition.Bottom-AltHeight; end else if (MyB<(AltWidth div 2)) then begin //MessageBox(ChildWindow,'Низ2','Test',MB_OK); swp.rcNormalPosition.Left:=MyB-(AltWidth div 2)+((AltWidth div 2)-MyB); swp.rcNormalPosition.Right:=swp.rcNormalPosition.Left+AltWidth; swp.rcNormalPosition.Bottom:=wp2.Top; swp.rcNormalPosition.Top:=swp.rcNormalPosition.Bottom-AltHeight; end else if (MyB>(XSCREEN-(AltWidth div 2))) then begin //MessageBox(ChildWindow,'Низ3','Test',MB_OK); swp.rcNormalPosition.Left:=MyB-(AltWidth div 2)-((AltWidth div 2)-(XSCREEN-MyB)); swp.rcNormalPosition.Right:=swp.rcNormalPosition.Left+AltWidth; swp.rcNormalPosition.Bottom:=wp2.Top; swp.rcNormalPosition.Top:=swp.rcNormalPosition.Bottom-AltHeight; end; end; swp.rcNormalPosition.TopLeft.X:=swp.rcNormalPosition.Left; swp.rcNormalPosition.TopLeft.Y:=swp.rcNormalPosition.Top; swp.rcNormalPosition.BottomRight.X:=swp.rcNormalPosition.Right; swp.rcNormalPosition.BottomRight.Y:=swp.rcNormalPosition.Bottom; if (swp.rcNormalPosition.Right>swp.rcNormalPosition.Left) and (swp.rcNormalPosition.Bottom>swp.rcNormalPosition.Top) and (swp.rcNormalPosition.Right>=0)and(swp.rcNormalPosition.Right<=XSCREEN)and (swp.rcNormalPosition.Left>=0)and(swp.rcNormalPosition.Left<=XSCREEN)and (swp.rcNormalPosition.Top>=0)and(swp.rcNormalPosition.Top<=YSCREEN)and (swp.rcNormalPosition.Bottom>=0)and(swp.rcNormalPosition.Bottom<=YSCREEN) then SetWindowPlacement(hWndAltDesk,@swp); // else //s:='left='+IntToStr(swp.rcNormalPosition.Left)+' top='+IntToStr(swp.rcNormalPosition.Top)+' right='+IntToStr(swp.rcNormalPosition.Right)+' bottom='+IntToStr(swp.rcNormalPosition.Bottom)+' tlx='+IntToStr(swp.rcNormalPosition.TopLeft.X)+' tlY='+IntToStr(swp.rcNormalPosition.TopLeft.Y)+' brx='+IntToStr(swp.rcNormalPosition.BottomRight.X)+' bry='+IntToStr(swp.rcNormalPosition.BottomRight.Y); //MessageBox(ChildWindow,PChar(S),'Test',MB_OK); end; function WindowProc(Window: HWnd; Message:UINT; WParam: WParam; LParam: LParam): Longint; stdcall; var DC: hDC; ps: TPaintStruct; wp:TRect; r,r1:TRect; p:TPoint; uFlags:UINT; CurHWND:HWND; xPos,yPos:integer; KeyState: TKeyboardState; Old:HGDIOBJ; OldMode:integer; buf:array[0..MAX_PATH+1]of char; i,bufcount:integer; FakeWnd:string; s:string; TP:TPMPARAMS ; Menu:HMENU; begin result := 0; case Message of WM_PAINT: begin DC:=BeginPaint(ChildWindow, ps); {Draw skin} GetClientRect(ChildWindow, r); uFlags := 0; uFlags := uFlags or DPEx_TILED; // uFlags:= uFlags or DPEx_CENTERED; { if (r.right<>bmp_BkAlt.Width)or(r.bottom<>bmp_BkAlt.Height) then StretchSkin(AData.MemoryDC,bmp_BkAlt, @bmp_Bk, r.right, r.bottom); } SelectObject(dc, bmp_BkAlt.Handle); DrawSkin(dc,dc, r, r, r, @bmp_BkAlt,AData.WallPaperInfo.DesktopBrush, uFlags); if ShowNum then begin Old := SelectObject(dc, Font.Handle); OldMode := SetBkMode(dc, TRANSPARENT); SetTextColor(dc, Color); for i:=0 to NumOfDeskTops-1 do begin SetRect(r1, DeskIco*i, 0, DeskIco*i+DeskIco, 24); DrawText(dc, PChar(Int2Str(i+1)), -1, r1, DT_VCENTER or DT_CENTER or DT_SINGLELINE or DT_NOCLIP or DT_NOPREFIX); end; SelectObject(dc, Old); SetBkMode(dc, OldMode); end; {End Draw Skin} EndPaint(ChildWindow, ps); exit; end; WM_MOUSEMOVE: begin SetTimer(ChildWindow,1,100,@WindowProc); if ShowOnMouseOver then BEGIN if not WeWork then begin GetWindowRect(hWndAltDesk,wp);//altDesk if (wp.TopLeft.X<>RecAlt.TopLeft.X)or(wp.TopLeft.Y<>RecAlt.TopLeft.Y)or(wp.BottomRight.X<>RecAlt.BottomRight.X)or(wp.BottomRight.Y<>RecAlt.BottomRight.Y) then SetPlace(); RecAlt:=wp; GetWindowRect(ChildWindow,wp);//MyWindow if (wp.TopLeft.X<>RecMy.TopLeft.X)or(wp.TopLeft.Y<>RecMy.TopLeft.Y)or(wp.BottomRight.X<>RecMy.BottomRight.X)or(wp.BottomRight.Y<>RecMy.BottomRight.Y) then SetPlace(); RecMy:=wp; WeWork:=true; TimerWork:=false; SendMessage(hWndAltDesk,WM_SYSCOMMAND,SC_RESTORE,0); end; END;//if ShowOnMouseOver end; WM_TIMER: begin if (GetWindowRect(hWndAltDesk,wp)=false)then //altDesk FindAltDesk(); if (wp.TopLeft.X<>RecAlt.TopLeft.X)or(wp.TopLeft.Y<>RecAlt.TopLeft.Y)or(wp.BottomRight.X<>RecAlt.BottomRight.X)or(wp.BottomRight.Y<>RecAlt.BottomRight.Y) then SetPlace(); RecAlt:=wp; GetWindowRect(ChildWindow,wp);//MyWindow if (wp.TopLeft.X<>RecMy.TopLeft.X)or(wp.TopLeft.Y<>RecMy.TopLeft.Y)or(wp.BottomRight.X<>RecMy.BottomRight.X)or(wp.BottomRight.Y<>RecMy.BottomRight.Y) then SetPlace(); RecMy:=wp; if WParam=2 then begin KillTimer(ChildWindow,1); KillTimer(ChildWindow,2); WeWork:=false; TimerWork:=false; SendMessage(hWndAltDesk,WM_SHOWWINDOW,0,SW_SHOWNORMAL); end; if WParam=1 then begin GetCursorPos(P); CurHWND:=WindowFromPoint(P); bufcount:=GetClassName(CurHWND,@buf,MAX_PATH); FakeWnd:=''; if bufcount>0 then for i:=0 to bufcount-1 do FakeWnd:=FakeWnd+buf[i]; if ((CurHWND=ChildWindow) or (CurHWND=hWndAltDesk) or (FakeWnd='FakeWnd'))and(CurHWND<>0) then begin KillTimer(ChildWindow,2); TimerWork:=false; WeWork:=true; end else begin if MyAutoHide then begin if not TimerWork then begin SetTimer(ChildWindow,2,TimeToHide,@WindowProc); TimerWork:=true; end; end else KillTimer(ChildWindow,1); end; end; end; WM_LBUTTONDOWN: begin case ClickOptions of 0:begin end; 1: // show altdesk begin SendMessage(hWndAltDesk,WM_SYSCOMMAND,SC_RESTORE,0); end;//1 2: // switch to desk top begin xPos:= LOWORD(lParam); // horizontal position of cursor yPos:= HIWORD(lParam); for i:=0 to NumOfDeskTops-1 do begin if ( (xPos>=DeskIco*i) and (xPos0 then begin FreePicture(@bmp_Bk); RtlZeroMemory(@bmp_Bk, sizeof(bmp_Bk)); FreePicture(@bmp_BkAlt); RtlZeroMemory(@bmp_BkAlt, sizeof(bmp_BkAlt)); FreeFont(@Font); DestroyWindow(ChildWindow); ChildWindow:=0; end; UnregisterClass(szName, hInstance); end; {----------------------------------------------------------------} exports InitGlobalModule, DoneModule, GetPluginInfo; end.