自作アプリから、別のアプリのステータスバーの文字列を
取得したいのですが、うまくいきません。
ステータスバーっていくつかに分かれていますよね。
そのうち左端の枠(第1ペイン?)の文字列は、
ステータスバーのクラス名からハンドルを取得して
GetWindowText(API)で取得できるのですが、
第2ペインの文字列が取得できません。
知りたいのは第2ペインの文字列なのです。(T_T)
どなたか良い解決法をご存知でしたらお願いします。
すいません、環境を書き忘れてました。
Windows2000(SP4)+Delphi6personalです。
ちなみに知りたいステータスバーのクラス名は
「msctls_statusbar32」です。
SB_GETTEXTメッセージで、WParamに1を、LParamに文字列を入れるためのバッファを渡せばよろしいかと。
# 申し訳ない、未確認です。
追記。
SB_GETTEXTは定義されていないようなので、$0402としてください。
さらに訂正です^^;
CommCtrlに定義されていました。
にしのさん ものしりですね
すげぇ ほんと表示されるよ。
ワクワクしたから、ついカキカキしてためしてしまった
procedure TForm1.Button1Click(Sender: TObject);
const
SB_GETTEXT = WM_USER+2;
SB_GETTEXTLENGTH = WM_USER+3;
SB_GETPARTS = WM_USER+6;
SB_ISSIMPLE = WM_USER+14;
var Buffer : PChar;
Handle, i , PanelCount ,BufferSize: integer;
s : string;
SimpleMode : Boolean;
begin
s := '';
Handle := StatusBar1.Handle;
SimpleMode := (SendMessage(Handle,SB_ISSIMPLE,0,0)<>0);
PanelCount := SendMessage(Handle,SB_GETPARTS,0,0);
for i := 0 to PanelCount-1 do
begin
BufferSize := SendMessage(Handle,SB_GETTEXTLENGTH,i,0);
GetMem(Buffer, BufferSize+1);
try
SendMessage(Handle,SB_GETTEXT,i,Integer(Buffer));
Buffer[BufferSize] := Char(0); // 念のため
s := s + Buffer + #13+#10;
finally
FreeMem(Buffer);
end;
if (SimpleMode) then Break;
end;
ShowMessage(s);
end;
にしのさん、らくしょう☆さん、レスありがとうございます。
早速らくしょう☆さんのコードで試してみました。
ところが、SB_GETTEXTLENGTHで各ペインの文字列の長さ(バイト長)までは
取得できているのですが、SB_GETTEXTで文字列そのものが
取得できないのです。
ShowMessge(s)で表ヲさせてみると、
文字のあるペインは「・Mホ」(半角のようですが、全角で表ヲしました)
文字の無いペインは「fF」(これは半角のまま表ヲしました)
と文字化けしてしまいます。
ちなみに、目的のアプリとは別の、例えばエクスプローラのステータスバーも
同じクラス名だったので試したところ、やはり同じように
文字化けします。
なぜなのでしょうか。ソ問ばかりですみませんがお願いします。
あれ。発言内容まで文字化けしている。おかしいな?
表ヲ->表示
ソ問->質問
もしかして僕のパソコンに問題ありか?
というわけで、この投稿は別の端末からしてみました。
うまく表示されますように。(ToT)丿
単純にバッファアドレスの指定の仕方が
変なんじゃないの?
ウィンドウによっては、Unicodeかもしれませんので、その場合はSendMessageWを利用すればできると思います。
別プロセスだからじゃないでしょうか?
Mr.XRAYさんのホームページにあるHalbowさんの資料館で説明されています。
"API With Delphi VCL"の第8章です。
http://homepage2.nifty.com/Mr_XRAY/
他アプリなんだから文字列バッファに VirtualAllocEx() か CreateFileMapping() をつかうのでは。
他のアプリにアクセスしていなかったので気が付きませんでした。
IEにアクセスしたら落ちました(-_-)
すみませんテキストの長さの部分間違っていました。
誤: BufferSize := SendMessage(Handle,SB_GETTEXTLENGTH,i,0);
訂: BufferSize := SendMessage(Handle,SB_GETTEXTLENGTH,i,0) and $ff;
です
他のアプリ
WM_GETTEXTLENGTHなら表示できるんですけど
SB_GETTEXT のときは空白がかえってきますね・・・
メモリも書き換えた方がよさそうですね。
僕お手上げです では(+_+)/~~~
名前のつけかたがよくないので
テキストの長さにBufferSize 入れてしまっているので
メモリ割り当ての時まちがうから、
nullの文字の分の1バイトを最初から足してたほうがいいですね
BufferSize := 1 + SendMessage(Handle,SB_GETTEXTLENGTH,i,0) and $ff;
では(>_<)/~~~
> BufferSize := 1 + SendMessage(Handle,SB_GETTEXTLENGTH,i,0) and $ff;
and $FF だと255までですね。ヘルプによれば
The low word specifies the length, in characters, of the text.
だから and $FFFF だと思います。
すみません。 最近つかってないので間違えました
&Fが4ビットだということを忘れていました (^_^;
上に書かれているMr.XRAYさんのTCommonMemory 使うと
他のソフトへアクセスできました。
Class[msctls_statusbar32]が使われているもので試しましたら
IE, outolook,Explorer は文字取得できました。
MicrosoftDocument Explorer では、取得できなかったです。
( SB_GETTEXTLENGTH で、長さが0がかえってくるようです)
procedure TForm1.Button1Click(Sender: TObject);
const
SB_GETTEXT = WM_USER+2;
SB_GETTEXTLENGTH = WM_USER+3;
SB_GETPARTS = WM_USER+6;
SB_ISSIMPLE = WM_USER+14;
var Buffer : PChar;
Handle, MemHdl, i , PanelCount ,BufferSize ,TextLen : integer;
SimpleMode : Boolean;
s : string;
var
TempCM : TCommonMemory;
begin
s := '';
Handle := StatusBar1.Handle;
SimpleMode := (SendMessage(Handle,SB_ISSIMPLE,0,0)<>0);
PanelCount := SendMessage(Handle,SB_GETPARTS,0,0);
for i := 0 to PanelCount-1 do
begin
BufferSize := 1 + LOWORD(SendMessage(Handle,SB_GETTEXTLENGTH,i,0));
TempCM := GetCommonMemory(Handle,BufferSize);
try
GetMem(Buffer,BufferSize+1);
try
if (BufferSize = 1) then
Buffer[0] := Char(0)
else
if (BufferSize > 1) then
begin
TextLen := LOWORD(SendMessage(Handle,SB_GETTEXT,i,LPARAM(TempCM.MemPtr)));
if (BufferSize > TextLen) then
begin
TempCM.Read(0,Buffer,TextLen);
Buffer[TextLen] := Char(0)
end
else
begin
ShowMessage(
Format(
'Handle[%d]' + #13+#10 +
' Roop[%d/%d]' + #13+#10 +
'エラー:BufferSize[%d] < TextLen[%d] '
,[ Handle
, i+1 ,PanelCount
,BufferSize,TextLen
]));
Buffer[0] := Char(0);
end;
end;
s := s + Buffer + #13+#10;
if (SimpleMode) then Break;
finally
FreeMem(Buffer);
end;
finally
TempCM.Free;
end;
end; // for
ShowMessage(s);
end;
if (SimpleMode) then Break;
消すか移動してください。
メモリ解放わすれになってしまいます
わたしもMr.XRAYさんのところのTCommonMemoryを利用させてもらって
できました。
しかし、よそのプロセスのメモリを読み込むだけでなく
書き込むこともできちゃうんですね。
これってかなり凄いことじゃないかと思うんですがどうでしょう?
とにかくみなさんありがとうございました。
ツイート | ![]() |