喫茶XRAYトップページ


[1190] 無題返信 削除
2007/4/9 (月) 21:11:10 TS
Mr.XRAYさん
いつもお世話になります。
Delphi7 XPで使用しています。
色々やってみたのですが判らないので教えて下さい。

他のプログラムのコンボボックスのデータを取得しようと
 Mr.XRAYさんのところの
 Halbow資料館の
 http://homepage2.nifty.com/Mr_XRAY/Halbow/VCL08.html#VChap8-1
 第8章 他のアプリのウィンドウ情報の取得 - 共有メモリ
 List 10の
 SendMessage(hStatusbar,XX_XXXXXX,i,LPARAM(CM.MemPtr))
 の XX_XXXXXX 部分を
 SB_GETTEXT ->  CB_GETLBTEXT
 SB_GETPARTS -> CB_GETLBTEXTLEN
 に変えてみたのですが、

実行するフォーム上にコンボボックスを張り付け
た同一フォーム上のコンボボックスの文字の取得は
出来るのですが、他のプログラムの文字は取得は
色々やったのですができませんでした。

CB_SETCURSEL  選択位置の指定
CB_GETLBTEXTLEN 文字数の取得
だけは受け付けてくれます。

これって出来ないんでしょうか。


[1191] 他アプリのコンボボックスの文字取得返信 削除
2007/4/9 (月) 21:22:10 TS
表題を付けるのを忘れてました。

[1192] 他アプリのコンボボックスの文字取得返信 削除
2007/4/9 (月) 21:33:24 TS
訂正します
>  SB_GETPARTS -> CB_GETLBTEXTLEN
    SB_GETPARTS -> CB_GETCOUNT


[1194] 他アプリのコンボボックスの文字操作返信 削除
2007/4/10 (火) 20:34:22 Mr.XRAY
▼ TSさん

TSさんがわからないものは私には分かりません。
という振りはさておいて、コンボボックスの操作だけであれば特に共有メモリ
を使用する必要はありませんが、いかがでしょう。

>  SendMessage(hStatusbar,XX_XXXXXX,i,LPARAM(CM.MemPtr))

lParamで共有メモリの情報を取得しなければ、あるいは取得可能なものは、
共有メモリの利用もいいかと思います。これについては、提示のHalbow資料館
の解説も、共有メモリの使用例というポリシーで、Halbowさんも書いています。

コンボボックスの操作だけであれば、
http://homepage2.nifty.com/Mr_XRAY/Delphi/plSetPrinter/OthesDialog.htm
が参考になると思います。年のため参考コードを以下に示します。
ただし、HDD内の半整備のコードですのであしからず。

受信側

unit ReceiverUnit;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  StdCtrls;

type
  TReceivForm = class(TForm)
    Edit1: TEdit;
    Button1: TButton;
    ComboBox1: TComboBox;
    procedure FormCreate(Sender: TObject);
    procedure Button1Click(Sender: TObject);
  private
    { Private 宣言 }
  public
    { Public 宣言 }
  end;

//送信側ではTReceivFormというクラス名のウィンドウに対して操作する
var
  ReceivForm: TReceivForm;

implementation

{$R *.DFM}

//=============================================================================
//  他のアプリから操作しやすいように,EditとComboBoxにID値を付けておく
//  当然であるが,Handleプロパティを持たないコントロールにはID値を付けられない
//  Edit1のテキストを空にするのにEdit1:=''; ではなくEdit1.Text:=EmptyStr; を使
//  用してみた。EmptyStrはSysUtilsにある
//=============================================================================
procedure TReceivForm.FormCreate(Sender: TObject);
begin
     SetWindowLong(Edit1.Handle,GWL_ID,1000);
     SetWindowLong(ComboBox1.Handle,GWL_ID,1100);
     Edit1.Text:=EmptyStr;
     ComboBox1.ItemIndex:=0;
end;
//=============================================================================
//  テキストをクリア
//=============================================================================
procedure TReceivForm.Button1Click(Sender: TObject);
begin
     Edit1.Clear;
end;


送信側

unit SenderUnit;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  StdCtrls, ExtCtrls;

type
  TSenderForm = class(TForm)
    Button1: TButton;
    Edit1: TEdit;
    Panel1: TPanel;
    Memo1: TMemo;
    procedure Button1Click(Sender: TObject);
  private
    { Private 宣言 }
  public
    { Public 宣言 }
  end;

var
  SenderForm: TSenderForm;

implementation

{$R *.DFM}

//=============================================================================
//  Button1をクリックすると
//  ID値が1000のコントロールに文字列をセットする
//  ID値が1100のコントロール(ここではコンボボックス)を操作
//=============================================================================
procedure TSenderForm.Button1Click(Sender: TObject);
var
     hWindow   : HWND;
     RevHandle : HWND;
     PStr      : PChar;
     Str       : String;
     i         : Integer;
     Cnt       : Integer;
     Len       : Integer;
begin
     //受取る側のウィンドウハンドル
     hWindow := FindWindow('TReceivForm',nil);
     if hWindow<>0 then begin
       //hWindowのID値が1000の子ウィンドウのハンドル
       RevHandle:=GetDlgItem (hWindow,1000);
       //そこにEdit1.Textを送る
       SendMessage(RevHandle,WM_SETTEXT,0,LPARAM(PChar(Edit1.Text)));


       Memo1.Lines.Clear;
       //hWindowのID値が1100の子ウィンドウのハンドル
       //ここではコンボボックス
       RevHandle:=GetDlgItem (hWindow,1100);
       //その項目数
       Cnt:=SendMessage(RevHandle,CB_GETCOUNT,0,0);
       Panel1.Caption:='対象コンボボックスの項目数 : '+IntToStr(Cnt);
       //削除の場合はdowntoで
       for i:=Cnt-1 downto 0 do begin
         //メモリ確保のために文字列の長さを取得
         Len:=SendMessage(RevHandle,CB_GETLBTEXTLEN,i,0);
         GetMem(PStr,Len+1);
         try
           //i番目の項目の文字列を取得
           SendMessage(RevHandle,CB_GETLBTEXT,i,LongInt(PStr));
           Str:=PStr;
           Memo1.Lines.Add(PStr);
         finally
           FreeMem(PStr);
         end;
         //対象コンボボックスのItemに東という文字が含まれてる場合は項目から削除
         if Pos('東',Str)<>0 then begin
           SendMessage(RevHandle,CB_DELETESTRING,i,0);
           if Cnt>2 then SendMessage(RevHandle,CB_SETCURSEL,1,0);
         end;
       end;
       //対象コンボボックスの項目数を再取得
       //ここではわかりきっているが確認のため
       Cnt:=SendMessage(RevHandle,CB_GETCOUNT,0,0);
       Panel1.Caption:='対象コンボボックスの項目数 : '+IntToStr(Cnt);
     end;
end;




[1195] 他アプリのコンボボックスの文字操作返信 削除
2007/4/10 (火) 20:37:34 Mr.XRAY
▼ TSさん

> 受信側

テストの時は、受信側のComboBoxに以下のItemをセットしていました。

東京都
大阪府
京都府
神奈川県


[1196] Re:他アプリのコンボボックスの文字操作返信 削除
2007/4/10 (火) 22:14:09 TS
Mr.XRAYさん

早速回答いただいてありがとうございます。

掲示していただいた、コードでコンボボックスの
データが取得できました。
あんなに苦労して色々やったのは何だったんでしょうね。

掲示でもある都道府県を他のプログラムから取得しようと
思ってやり始めたのですが。
そのプログラムの動作も確認しました。
そのプログラムの東京もしっかり消えました。

> lParamで共有メモリの情報を取得しなければ、あるいは取得可能なものは、
> 共有メモリの利用もいいかと思います。これについては、提示のHalbow資料館
> の解説も、共有メモリの使用例というポリシーで、Halbowさんも書いています。


>http://homepage2.nifty.com/Mr_XRAY/Delphi/plSetPrinter/OthesDialog.htm
ここも見せて貰っていたのですが、共有メモリを使っておられ
なかったので、同一プログラム内になるのかと思ってました。
どこが悪かったのか、共有メモリを使用すると駄目の
場合もあるのでしょか、使い方は違えていないと思うのですが。

それにしても助かりました。

ではまた宜しくお願いします。

[1197] Re2:他アプリのコンボボックスの文字操作返信 削除
2007/4/10 (火) 22:35:31 Mr.XRAY
▼ TSさん

> どこが悪かったのか、共有メモリを使用すると駄目の
> 場合もあるのでしょか、使い方は違えていないと思うのですが。


共有メモリを特に使わなくてもいいということではないかと、勝手に理解
していたりして>自分 (笑)。

ところで、タイトルなんですが、他の方が見てわかりやすいように変更して
しまいましたので、TSさんのも変更しておきます。
なんか掲示板の動作が重たいです。niftyサーバ、整備中なのかな。


[1198] Re3:他アプリのコンボボックスの文字操作返信 削除
2007/4/11 (水) 20:39:27 TS
▼ Mr.XRAYさん
最初に戻ってHalbowさんのList 10でテストしてみました。

ステータスバーではやっぱり共有メモリを使用しないと
データを取得できず。

コンポボックスでは共有メモリを使用すると駄目みたいです。

見た目が同じ様な命令文なので、どこが違うのか良く
わかりませんが、これですっきりしました。

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


[1200] Re4:他アプリのコンボボックスの文字操作返信 削除
2007/4/13 (金) 18:56:33 Mr.XRAY
▼ TSさん

> コンポボックスでは共有メモリを使用すると駄目みたいです。

やってみました。テキストボックス(TEdit)も取得できません。
共有メモリにも何も入らないようです。
多分、これらがウィンドウテキストがウィンドウの属性の一つで、
仮想メモリ空間のアドレスの問題を自動的に解決してくれている例外的な
メッセージなのではないかと思います。
(WM_GETTEXT,WM_SETTEXTの部類)

OSが仮想メモリ空間のアドレスの問題を自動的に解決してくれている例
外的なメッセージしてはWM_COPYDATA というのがありますね。


INCM/CMT
Cyclamen v3.82