HSPポータル
サイトマップ お問い合わせ


HSPTV!掲示板


未解決 解決 停止 削除要請

2020
0928
こいる外部アプリのステータスバーのテキストを変更する方法4解決


こいる

リンク

2020/9/28(Mon) 13:58:55|NO.91469

外部アプリに設置されているステータスバーの、テキストを変更する方法が知りたいです。

普通にSB_SETTEXTを送ると、送り先のアプリが落ちてしまいます。

// メモ帳を対象にする #uselib "user32.dll" #func FindWindowEx "FindWindowExA" sptr,sptr,sptr,sptr #func FindWindow "FindWindowA" sptr,sptr #define SB_SETTEXT $00000401 exec "notepad" hParent = FindWindow( "Notepad", "無題 - メモ帳") hStatusbar = FindWindowEx( hParent, 0, "msctls_statusbar32", 0) sendmsg hStatusbar, SB_SETTEXT, 0, "test"

DrawStatusText関数を使うと、一応テキストを描画することができるのですが、
フォントの種類とサイズを変更する方法が分からないです。

また、パーツごとに描画する方法も分からないです。
パーツのRECTを取得できればできるはずなのですが、
SB_GETRECTメッセージを送ってもアプリが落ちてしまい、取得ができません。

#uselib "user32.dll" #func FindWindowEx "FindWindowExA" sptr,sptr,sptr,sptr #func FindWindow "FindWindowA" sptr,sptr #func GetDC "GetDC" sptr #func GetClientRect "GetClientRect" sptr,sptr #uselib "comctl32.dll" #func DrawStatusText "DrawStatusText" sptr,sptr,sptr,sptr #define SBT_NOBORDERS $00000100 exec "notepad" hParent = FindWindow( "Notepad", "無題 - メモ帳") hStatusbar = FindWindowEx( hParent, 0, "msctls_statusbar32", 0) dim RECT,4 GetClientRect hStatusbar, varptr(RECT) DrawStatusText GetDC(hStatusbar), varptr(RECT), "test", SBT_NOBORDERS

どうすればできるのでしょうか?
ご教示ください。



この記事に返信する


TOMATO

リンク

2020/9/28(Mon) 15:54:59|NO.91471

> 普通にSB_SETTEXTを送ると、送り先のアプリが落ちてしまいます。

WM_GETTEXT, WM_SETTEXT, WM_COPYDATA のような別プロセスを跨いでも問題ないウィンドウメッセージではないので、
普通に送信した場合は落ちてしまうのは当然かなぁ。

試してないですが、相手側のプロセス空間のメモリを作成して、
そこに書き換える文字列のデータを書き込み、
SB_SETTEXT を送信すれば上手くいくんじゃないかなぁ。

------------------------------

GetWindowThreadProcessId() // メモ帳のウィンドウハンドルからプロセスIDを取得する ↓ OpenProcess() // メモ帳のプロセスIDからプロセスハンドルを取得する ↓ VirtualAllocEx() // メモ帳のプロセスにメモリを確保する(メモリポインタを取得) ↓ WriteProcessMemory() // 上で確保したメモリポインタへ文字列データを書き込む ↓ SendMessage SB_SETTEXT // lparam に 文字列書き込み済みのメモリポインタを指定する ------------------------------

※ ただし、HSPは標準は32bitアプリなので、送信先も32bitアプリでないとダメ。
メモ帳だと C:\Windows\SysWOW64\notepad.exe の32bit版でないと上手くいかなそう。



TOMATO

リンク

2020/9/28(Mon) 16:13:15|NO.91472

補足

64ビットOS上でHSPから exec "notepad.exe" をした場合は、
WOW64のリダイレクト機能が動作して32ビット版のメモ帳が起動するので、
exec "C:\\Windows\\SysWOW64\\notepad.exe"
のようなことはしなくて大丈夫です。



こいる

リンク

2020/9/28(Mon) 17:27:15|NO.91474

丁寧にありがとうございます。

別プロセスがダメなら、同じプロセスのメモリを使おうというわけですか。
面白いですね。

手順通りにすると上手くいきました!
メモリサイズは適当に64byteにしてみました。

#uselib "user32.dll" #func FindWindowEx "FindWindowExA" sptr,sptr,sptr,sptr #func FindWindow "FindWindowA" sptr,sptr #func GetWindowThreadProcessId "GetWindowThreadProcessId" sptr,sptr #uselib "kernel32.dll" #func OpenProcess "OpenProcess" sptr,sptr,sptr #func VirtualAllocEx "VirtualAllocEx" sptr,sptr,sptr,sptr,sptr #func WriteProcessMemory "WriteProcessMemory" sptr,sptr,sptr,sptr,sptr #func CloseHandle "CloseHandle" sptr #define SB_SETTEXT $00000401 exec "notepad" hParent = FindWindow( "Notepad", "無題 - メモ帳") hStatusbar = FindWindowEx( hParent, 0, "msctls_statusbar32", 0) // メモ帳のウィンドウハンドルからプロセスIDを取得する dim pId GetWindowThreadProcessId hParent, varptr(pId) // メモ帳のプロセスIDからプロセスハンドルを取得する hProcess = OpenProcess(0x0008|0x0020, 0, pId); PROCESS_VM_OPERATION, PROCESS_VM_WRITE // メモ帳のプロセスにメモリを確保する(メモリポインタを取得) VirtualAllocEx hProcess, 0, 64, 0x1000, 0x04; MEM_COMMIT, PAGE_READWRITE baseAddress = stat mes "BaseAddress: "+baseAddress // 上で確保したメモリポインタへ文字列データを書き込む WriteProcessMemory hProcess, baseAddress, "test", 64, 0 ; 一応ハンドルを閉じる CloseHandle hProcess // lparam に 文字列書き込み済みのメモリポインタを指定する sendmsg hStatusbar, SB_SETTEXT, 0, baseAddress mes "SB_SETTEXT: "+stat

しかし、VirtualAllocEx関数のp4とp5はこの設定で大丈夫なのでしょうか?
メモリ操作は初めてでよく分からないので不安です。



こいる

リンク

2020/9/30(Wed) 21:46:17|NO.91501

VirtualAllocEx関数のp4とp5については、
メモリのこと(コミット、予約など)を少し調べて自己解決しました。

ありがとうございました。



ONION software Copyright 1997-2023(c) All rights reserved.