unit ManageWindowPage; interface uses Tocsg.Obj, System.Classes, Winapi.Windows, Vcl.Forms, Vcl.ComCtrls, System.Generics.Collections, System.SysUtils, Tocsg.Process, superobject, Winapi.Messages; const DAT_WNDPAGES = 'WndPages.dat'; type TWndTabSheet = class; TWndFrame = class(TFrame) protected OwnerTabSheet_: TWndTabSheet; public Constructor Create(aOwner: TComponent); override; property OwnerTabSheet: TWndTabSheet read OwnerTabSheet_; end; TWndFrameClass = class of TWndFrame; TWndKind = (wkNormal); PWndInfo = ^TWndInfo; TWndInfo = record WndKind: TWndKind; ProcPath: String; ProcID: NativeUInt; WndHandle: HWND; WndFrameClass: TWndFrameClass; OrzWndRect: TRect; // ÆûÀÌ ¿ø»óº¹±¸(ÆûÀÌ Æ÷ÇԵDZâ Àü) µÉ¶§ÀÇ À§Ä¡/Å©±â·Î º¯Çϱâ À§ÇØ »ç¿ë 14_0421 22:21:37 sunk OrzBorderStyle, OrzBorderExStyle: NativeInt; ProcInfo: TTgProcessInfo; end; TWndTabSheet = class(TTabSheet) private WndInfo_: TWndInfo; WndFrame_: TWndFrame; public Constructor Create(aOwner: TComponent; aWndInfo: TWndInfo); Destructor Destroy; override; property WndInfo: TWndInfo read WndInfo_; end; TWndInfoEnumerator = TEnumerator; TManagerWindowPage = class(TTgObject) private DcWndPages_: TDictionary; // DcProcessTabSheet_: TDictionary; DcWndTabSheet_: TDictionary; procedure OnWndPage(Sender: TObject; const Item: PWndInfo; Action: TCollectionNotification); procedure RemoveWndPage(WndHandle: HWND); procedure SavePages; procedure LoadPages; // function GetWndTabSheetByPID(const dwPid: DWORD): TWndTabSheet; function GetWndTabSheetByHWND(const hWindow: HWND): TWndTabSheet; public Constructor Create; Destructor Destroy; override; procedure ClearPages; procedure AddWndPage(aWndInfo: TWndInfo); function GetWndPage(aWndHandle: HWND): PWndInfo; function GetWndTabSheet(aWndHandle: HWND): TWndTabSheet; function GetWndInfoEnumerator: TWndInfoEnumerator; procedure DeleteWndTabSheetFromHWND(const hWindow: HWND; bWndDestroyAfter: Boolean = false); procedure DeleteWndTabSheetFromPid(const dwPid: DWORD); // property WndTabSheet[const hWindow: HWND]: TWndTabSheet read GetWndTabSheetByHWND; end; var gWndPage: TManagerWindowPage = nil; implementation uses Vcl.Controls, Tocsg.Safe, Tocsg.JSON, Tocsg.Path, Define, Tocsg.WndUtil, Tocsg.Convert; { TWndFrame } Constructor TWndFrame.Create(aOwner: TComponent); begin Inherited Create(aOwner); ASSERT(aOwner is TWndTabSheet); OwnerTabSheet_ := aOwner as TWndTabSheet; end; { TWndTabSheet } Constructor TWndTabSheet.Create(aOwner: TComponent; aWndInfo: TWndInfo); begin Inherited Create(aOwner); WndInfo_ := aWndInfo; WndFrame_ := WndInfo_.WndFrameClass.Create(Self); WndFrame_.Parent := Self; WndFrame_.Align := alClient; if gWndPage <> nil then gWndPage.DcWndTabSheet_.Add(WndInfo_.WndHandle, Self); // gWndPage.DcProcessTabSheet_.Add(WndInfo_.ProcID, Self); end; Destructor TWndTabSheet.Destroy; begin if gWndPage <> nil then begin // gWndPage.DcProcessTabSheet_.Remove(WndInfo_.ProcID); gWndPage.DcWndTabSheet_.Remove(WndInfo_.WndHandle); // todo : Æ÷ÇÔ À©µµ¿ì(ÇÁ·Î¼¼½º)¸¦ °°ÀÌ ´ÝÀ»°ÇÁö ¾Æ´Ô »¬°ÇÁö ¹¯±â/¿É¼Ç // if (GetProcessPathFromPID(WndInfo_.ProcID) <> '') and // (MessageBox(Handle, 'ÇÏÀ§ ÇÁ·Î¼¼½ºµµ ÇÔ²² Á¾·áÇϽðڽÀ´Ï±î?', // APP_NAME, MB_ICONQUESTION or MB_YESNO) = IDYES) then // begin // TerminateProcessFromPID(WndInfo_.ProcID); // WndInfo_.ProcID := 0; // end; // if IsWindow(WndInfo_.WndHandle) and //// (GetProcessPathFromPID(WndInfo_.ProcID) <> '') and // (MessageBox(Handle, 'ÇÏÀ§ À©µµ¿ìµµ ÇÔ²² Á¾·áÇϽðڽÀ´Ï±î?', // APP_NAME, MB_ICONQUESTION or MB_YESNO) = IDYES) then // begin // PostMessage(WndInfo_.WndHandle, WM_CLOSE, 0, 0); //// WndInfo_.ProcID := 0; // end; if GetProcessNameByPid(WndInfo_.ProcID) <> '' then gWndPage.RemoveWndPage(WndInfo_.WndHandle); end; Inherited; end; { TManagerWindowPage } Constructor TManagerWindowPage.Create; begin Inherited Create; ASSERT(gWndPage = nil); gWndPage := Self; DcWndPages_ := TDictionary.Create; DcWndPages_.OnValueNotify := OnWndPage; // DcProcessTabSheet_ := TDictionary.Create; DcWndTabSheet_ := TDictionary.Create; LoadPages; end; Destructor TManagerWindowPage.Destroy; begin gWndPage := nil; FreeAndNil(DcWndTabSheet_); // Á¤»ó Á¾·áµÇ¸é ±âÁ¸ Æ÷ÇÔ ÆûÀ» Á¤»óÀ¸·Î µ¹·ÁÁÖ°í, ºñÁ¤»ó Á¾·á·Î º¸ÀÌÁö ¾Ê°Ô ºñ¿öÁØ´Ù 14_0421 22:32:23 sunk DcWndPages_.Clear; SavePages; FreeAndNil(DcWndPages_); Inherited; end; procedure TManagerWindowPage.OnWndPage(Sender: TObject; const Item: PWndInfo; Action: TCollectionNotification); var WndPlacement: TWindowPlacement; begin case Action of cnAdded: begin ZeroMemory(@Item.OrzWndRect, SizeOf(Item.OrzWndRect)); if GetWindowPlacement(Item.WndHandle, WndPlacement) then Item.OrzWndRect := WndPlacement.rcNormalPosition; Item.OrzBorderStyle := GetWindowStyle(Item.WndHandle); Item.OrzBorderExStyle := GetWindowExStyle(Item.WndHandle); end; cnRemoved: begin if GetProcessNameByPid(Item.ProcID) <> '' then begin Winapi.Windows.SetParent(Item.WndHandle, GetDesktopWindow); if (Item.OrzWndRect.Width <> 0) and (Item.OrzWndRect.Height <> 0) then MoveWindow(Item.WndHandle, Item.OrzWndRect.Left, Item.OrzWndRect.Top, Item.OrzWndRect.Width, Item.OrzWndRect.Height, true); SetWindowLong(Item.WndHandle, GWL_STYLE, Item.OrzBorderStyle); SetWindowLong(Item.WndHandle, GWL_EXSTYLE, Item.OrzBorderExStyle); end; if Item.ProcInfo <> nil then FreeAndNil(Item.ProcInfo); Dispose(Item); end; cnExtracted: ; end; end; procedure TManagerWindowPage.ClearPages; begin DcWndPages_.Clear; SavePages; end; procedure TManagerWindowPage.AddWndPage(aWndInfo: TWndInfo); var pInfo: PWndInfo; begin if (aWndInfo.WndHandle <> 0) and not DcWndPages_.ContainsKey(aWndInfo.WndHandle) then begin New(pInfo); pInfo^ := aWndInfo; DcWndPages_.Add(pInfo.WndHandle, pInfo); SavePages; end; end; function TManagerWindowPage.GetWndPage(aWndHandle: HWND): PWndInfo; begin if DcWndPages_.ContainsKey(aWndHandle) then Result := DcWndPages_[aWndHandle] else Result := nil; end; function TManagerWindowPage.GetWndTabSheet(aWndHandle: HWND): TWndTabSheet; begin if DcWndTabSheet_.ContainsKey(aWndHandle) then Result := DcWndTabSheet_[aWndHandle] else Result := nil; end; //function TManagerWindowPage.GetWndTabSheetByPID(const dwPid: DWORD): TWndTabSheet; function TManagerWindowPage.GetWndTabSheetByHWND(const hWindow: HWND): TWndTabSheet; begin if DcWndTabSheet_.ContainsKey(hWindow) then Result := DcWndTabSheet_[hWindow] else Result := nil; end; procedure TManagerWindowPage.RemoveWndPage(WndHandle: HWND); begin if DcWndPages_.ContainsKey(WndHandle) then begin DcWndPages_.Remove(WndHandle); SavePages; end; end; function TManagerWindowPage.GetWndInfoEnumerator: TWndInfoEnumerator; begin Result := DcWndPages_.Values.GetEnumerator end; procedure TManagerWindowPage.DeleteWndTabSheetFromHWND(const hWindow: HWND; bWndDestroyAfter: Boolean = false); var WndTabSheet: TWndTabSheet; begin if DcWndTabSheet_.ContainsKey(hWindow) then begin WndTabSheet := DcWndTabSheet_[hWindow]; DcWndTabSheet_.Remove(hWindow); if bWndDestroyAfter then WndTabSheet.WndInfo_.WndHandle := 0; WndTabSheet.Free; end; end; procedure TManagerWindowPage.DeleteWndTabSheetFromPid(const dwPid: DWORD); var enum: TEnumerator; begin Guard(enum, DcWndTabSheet_.Values.GetEnumerator); while enum.MoveNext do begin if enum.Current.WndInfo_.ProcID = dwPid then begin DcWndPages_.Remove(enum.Current.WndInfo_.WndHandle); enum.Current.Free; end; end; end; procedure TManagerWindowPage.SavePages; var WndPageList: TStringList; enum: TWndInfoEnumerator; begin Guard(WndPageList, TStringList.Create); Guard(enum, GetWndInfoEnumerator); while enum.MoveNext do WndPageList.Add(TTgJson.ValueToJsonAsString(enum.Current^)); WndPageList.SaveToFile(GetRunExePathDir + DAT_WNDPAGES); end; procedure TManagerWindowPage.LoadPages; var sPath: String; WndPageList: TStringList; i: Integer; O: ISuperObject; WndInfo: TWndInfo; pInfo: PWndInfo; begin sPath := GetRunExePathDir + DAT_WNDPAGES; if FileExists(sPath) then begin Guard(WndPageList, TStringList.Create); WndPageList.LoadFromFile(GetRunExePathDir + DAT_WNDPAGES); for i := 0 to WndPageList.Count - 1 do begin pInfo := nil; try O := SO(WndPageList[i]); WndInfo.WndKind := TTgRtti.Int64ToSetType(O.I['WndKind']); WndInfo.ProcPath := O.S['ProcPath']; WndInfo.ProcID := O.I['ProcID']; WndInfo.WndHandle := O.I['WndHandle']; WndInfo.WndFrameClass := TTgJson.GetDataAsType(O['WndFrameClass']); if UpperCase(ExtractFileName(WndInfo.ProcPath)) = UpperCase(GetProcessNameByPID(WndInfo.ProcID)) then begin WndInfo.ProcInfo := TTgProcessInfo.Create(WndInfo.ProcID); New(pInfo); pInfo^ := WndInfo; ShowWindow(pInfo.WndHandle, SW_SHOWNORMAL); // pInfo.WndHandle := GetWndHandleFromPID(WndInfo.ProcID); DcWndPages_.Add(pInfo.WndHandle, pInfo); end else WndInfo.ProcInfo := nil; except if pInfo <> nil then Dispose(pInfo); continue; end; end; SavePages; end; end; end.