→[[OS関連:http://www.kernel-net.ne.jp/tech/index.php?OS%B4%D8%CF%A2]] →COM技術関連 #contents *Tips [#mf9390b5] -[[Windowsパス名の落とし穴>http://www.ipa.go.jp/security/awareness/vendor/programming/b08_01.html]] -[[他のアプリのウィンドウハンドルを得る>http://www.wwlnk.com/boheme/delphi/tips/tec0440.htm]] --FindWindowにクラス名を渡す -[[Win32雑学ノート>http://hp.vector.co.jp/authors/VA000092/win32/win32trivia.html]] --セッション−ウンドウステーション−デスクトップの関連について説明がある ---これらのデスクトップのさらに上位に位置するのがウィンドウステーションである。ウィンドウステーションには、大きく分けて I/O ウィンドウステーションと Non I/O ウィンドウステーションの2種類がある。後述するセッションには高々ひとつだけ I/O ウィンドウステーションが存在できる。 I/O ウィンドウステーションとは、文字通り Input / Output を行うウィンドウステーション。つまり、セッションにはひとつだけ、入力を受付画面に出力することのできるウィンドウステーションがある。先に述べた二つのデスクトップも、この I/O ウィンドウステーションに属する。 ---では Non I/O ウィンドウステーションは何のために用意されているのだろう。その答えは「サービス」である。サービスは入出力の必要はない。 Non I/O ウィンドウステーションはセッションにいくつでも存在できる。サービスが動作する LUID に応じて Non I/O ウィンドウステーションが作られ、それぞれ GUI 的に隔離された空間に置かれる。 -[[UI Automation overview>http://www.codeproject.com/WPF/UIAutomation1.asp]] *Professional User Interface Suite [#y634b152] -http://www.codeproject.com/docking/prod_profuis.asp *DirectX/WPF [#g404c2f6] -[[WPF/MDX:http://www.atmarkit.co.jp/fdotnet/directxworld/directxworld03/directxworld03_02.html]] --MDX=Managed DirectX -[[XNA解説:http://www.atmarkit.co.jp/fdotnet/directxworld/directxworld03/directxworld03_01.html]] -[[WPF概要:http://www.dodgson.org/omo/t/?date=20060922#p10]] 2006.9.25 -[[DirectXの真実:http://www.atmarkit.co.jp/fdotnet/directxworld/directxworld01/directxworld01_01.html]] *GDI/GDI+ [#paeaec10] -[[Fuzzy DropShadows in GDI++:http://www.codeproject.com/useritems/FuzzyDropShadows.asp]] ***gdi++.dll [#c66469e0] -http://drwatson.nobody.jp/gdi++/ -フォントの描画をフックして滑らかな表示にする -[[関連スラド記事:http://slashdot.jp/developers/article.pl?sid=06/09/22/1617251]] *画面のキャプチャ方法三種類 [#q692acd7] -http://www.codeproject.com/dialog/screencap.asp -GDI経由、DirectX経由、Windows Media API経由の3種類 *Taskbar Progress Control [#x0743f75] -http://www.codeproject.com/statusbar/taskbarctrl.asp *ウィンドウハンドルからモジュール名を得る [#i0c02cd3] -http://www.codeproject.com/cpp/ModuleNameFromWindwHandle.asp *Processing Global Mouse and Keyboard Hooks in C# [#mb551c58] -http://www.codeproject.com/csharp/globalhook.asp *SetUpDIxxx関数によるデバイス情報の列挙 [#vabf01ea] -http://www.codeproject.com/useritems/SimpleSetup.asp *タスクバーをプログラムから制御する [#jbb9b341] -PostMessageを使う -http://www.codeproject.com/useritems/Taskbar_Manipulation.asp * デスクトップ上のウィンドウをグリッドに沿って合わせるユーティリティ [#m651e46e] -メッセージフックのサンプル。Delphi -http://codezine.jp/a/article.aspx?aid=369 *現在ログオンしているユーザの情報を得る [#m4d8e543] -http://www.codeproject.com/useritems/LoggedOnUSer.asp (Part1) -http://www.codeproject.com/useritems/LoggedOnUsersPart2.asp (Part2) *GetSystemMetricsのパラメータの微妙な違い [#m2a633f9] [DllImport("user32.dll")] public static extern int GetSystemMetrics(int nIndex); const int SM_CXSCREEN = 0; const int SM_CYSCREEN = 1; //デスクトップ画面全体 const int SM_CXFULLSCREEN =16; const int SM_CYFULLSCREEN =17; //フルスクリーンにしたときのクライアント領域(ステータスバー分が入らない) const int SM_CXMAXIMIZED=61; const int SM_CYMAXIMIZED=62; //フルスクリーンにしたときの全体(タスクバー分が入らない) *ウィンドウの強制前だし要件への対応 [#z99d3f9a] 単純にSetForegroundWindow APIとかを使うだけではダメである件について -http://techtips.belution.com/ja/vc/0012/ void SetAbsoluteForegroundWindow(HWND hWnd) { int nTargetID, nForegroundID; DWORD sp_time; // フォアグラウンドウィンドウを作成したスレッドのIDを取得 nForegroundID = GetWindowThreadProcessId(GetForegroundWindow(), NULL); // 目的のウィンドウを作成したスレッドのIDを取得 nTargetID = GetWindowThreadProcessId(hWnd, NULL ); // スレッドのインプット状態を結び付ける AttachThreadInput(nTargetID, nForegroundID, TRUE ); // TRUE で結び付け // 現在の設定を sp_time に保存 SystemParametersInfo( SPI_GETFOREGROUNDLOCKTIMEOUT,0,&sp_time,0); // ウィンドウの切り替え時間を 0ms にする SystemParametersInfo( SPI_SETFOREGROUNDLOCKTIMEOUT,0,(LPVOID)0,0); // ウィンドウをフォアグラウンドに持ってくる SetForegroundWindow(hWnd); // 設定を元に戻す SystemParametersInfo( SPI_SETFOREGROUNDLOCKTIMEOUT,0,sp_time,0); // スレッドのインプット状態を切り離す AttachThreadInput(nTargetID, nForegroundID, FALSE ); // FALSE で切り離し } *DLLの関数差し替え [#ibc0b27d] -参考資料:http://www.users.gr.jp/blogs/hidori/archive/2005/07/25/14423.aspx BOOL ReplaceDllProc( LPCTSTR lpSourceModuleName, // 置換対象の DLL 関数が格納されているモジュールの名前 LPVOID lpCurProc, // 置換対象の DLL 関数のアドレス LPVOID lpNewProc, // 新しい DLL 関数のアドレス HMODULE hNewProcModule // 新しい DLL 関数が格納されているモジュールのハンドル ) { ULONG ulSize = 0; PIMAGE_IMPORT_DESCRIPTOR pImportDesc = (PIMAGE_IMPORT_DESCRIPTOR) ::ImageDirectoryEntryToData(hNewProcModule, TRUE,IMAGE_DIRECTORY_ENTRY_IMPORT, &ulSize); if (!pImportDesc) { return FALSE; } for (; pImportDesc->Name; pImportDesc++) { LPCTSTR lpModName = (LPCTSTR) ((PBYTE) hNewProcModule + pImportDesc->Name); if (!_tcsicmp (lpModName, lpSourceModuleName)) { break; } } if (!pImportDesc->Name) { return FALSE; } PIMAGE_THUNK_DATA pThunk = (PIMAGE_THUNK_DATA) ((PBYTE) hNewProcModule + pImportDesc->FirstThunk); for (; pThunk->u1.Function; pThunk++) { LPVOID* ppfn = (LPVOID*) &(pThunk->u1.Function); BOOL fFound = (*ppfn == lpCurProc); if (fFound) { ::WriteProcessMemory (::GetCurrentProcess(), ppfn, &lpNewProc, sizeof(lpNewProc), 0); return TRUE; } } return FALSE; } *DLLの共有セグメント(C++) [#u6efc7c4] DLL のソースコードに #pragma comment(linker,"/section:SHARED,rws") #pragma data_seg("SHARED") HWND hwndOwner = 0; HHOOK hhk = 0; #pragma data_seg() のように記述。 #pragma data_seg は、#pragma data_seg で括られた区間がデータセグメントであること、セクション名が "SHARED" であることを示し #pragma comment ディレクティブは、リンカに対する指示で、"SHARED" と名前付けられたセクションが「読み書き可能、共有」の属性を持つことを指定 この2つの記述により、変数 hwndOwner と hhk は、この DLL をロードしたプロセス間で共有される。 なお、共有する変数は HWND hwndOwner = 0; のように必ず初期化すること。 これを忘れると、変数が共有されません。