MsgHandlerでフックできない場合は?


  2014-02-27 05:03:33  No: 46084

長文になりましたが、よろしくお願いします。
環境はWindows7  Delphi6  Personalです。
SDIスタイルのアプリを勉強しています。
下記は複数のサブフォームを作成する例です。
サブフォームForm2にbutton1,2,3とLabel1とMemo1を貼り付けています。
button1は新規サブフォーム作成です。
質問:MsgHandlerでMemo1にファイルをドロップしてファイルパスを取得したいと
下記コードをサンプルとして引用しました。(私レベルでは書けません(^_^;)
一番最後に作成したサブフォームにドロップすれば取得しますが、
前に作成したサブフォームを最前画面(アクティブ)にして、ドロップしても
取得できません。(カウンターが止まっているので)
どのサブフォームでも最前画面にすれば、ファイルパスを取得できるように
するには、
どのようなコードを書けばいいのでしょうか。
よろしくお願いします。
なお下記コードはhttp://mrxray.on.coocan.jp/Delphi/plSamples/710_SDIStyleApp.htm
のサンプルを投稿用にシンプルさせてもらいました。
//------------------------------------------プロジェクトファイル
program Project1;
uses
  Forms,
  Windows,
  Messages,
  Unit1 in 'Unit1.pas' {Form1},
  Unit2 in 'Unit2.pas' {Form2};
{$R *.res}
const
  UniqueName:string = 'Mr.XRAYSDIApp';
var
   hWindow : THandle;
function IsPrevAppExist(Name:string):Boolean;//  すでに本アプリが起動中かを調査
begin   //  起動中ならTrueを返す
  Result := False;
  CreateMutex(nil,true,PChar(Name));
  if GetLastError = ERROR_ALREADY_EXISTS then Result := True;
end;
//  まだ本アプリが起動していない場合メインフォームを非表示で作成
begin
  if IsPrevAppExist(UniqueName) then
  begin
    hWindow:=FindWindow('TForm1',nil);
    SetForegroundWindow(hWindow);
    SendMessage(hWindow,WM_USER+50,0,0);
  end
  else
  begin
    SetProp(Application.Handle,PChar(UniqueName),1111);
    Application.Initialize;
    //Delphi2007以上
    {$IF CompilerVersion > 18.49}
    Application.MainFormOnTaskbar := True;
    {$IFEND}
    Application.CreateForm(TForm1, Form1);
    //メインフォームは非表示とする
    Application.ShowMainForm:=False;
    Application.Run;
    RemoveProp(Application.Handle,PChar(UniqueName));
  end;
end.
//-------------------------------------メインフォーム
unit Unit1;
interface
uses
   Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  StdCtrls;
type
  TForm1 = class(TForm)
    procedure FormCreate(Sender: TObject);
  private
    { Private 宣言 }
  public
    { Public 宣言 }
    FormNumber : Integer;
    procedure CreateSubForm;
    procedure WMUserMessage(var msg:TMessage);message WM_USER + 50;
  end;
var
  Form1: TForm1;
implementation
uses Unit2;
{$R *.dfm}
procedure TForm1.FormCreate(Sender: TObject);
begin
    FormNumber:=0;
    CreateSubForm;
end;
//  実際に表示するサブフォームの生成
procedure TForm1.CreateSubForm;
var
    AForm : TForm2;
    Str   : String;
begin
    inc(FormNumber);
    Str   :='SDIアプリサンプル ['+IntToStr(FormNumber)+']';
    AForm :=TForm2.Create(Self);
    AForm.Show;
    AForm.Caption:=Str;
end;
//二重起動の場合はサブフォームを作成する
procedure TForm1.WMUserMessage(var msg: TMessage);
begin
    CreateSubForm;
end;
end.
//---------------------------------サブフォーム
unit Unit2;
interface
uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  Menus, StdCtrls, StdActns, ActnList, ExtCtrls ,ShellAPI ;
type
  TForm2 = class(TForm)
    Panel1: TPanel;
    Button1: TButton;
    Button2: TButton;
    Button3: TButton;
    Memo1: TMemo;
    Label1: TLabel;
    procedure FormShow(Sender: TObject);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
    procedure Button3Click(Sender: TObject);
  private
    { Private 宣言 }
    procedure MsgHandler(var Msg: TMsg; var Handled: Boolean);
  protected
    procedure CreateParams(var Params: TCreateParams); override;
  public
    { Public 宣言 }
  end;
var
    Form2: TForm2;
    NotFirstForm: Boolean;
    counter:integer;
implementation
uses Unit1;
{$R *.dfm}
procedure TForm2.MsgHandler(var Msg: TMsg; var Handled: Boolean);
var
    FileNames:array[0..255] of Char;
    Files :Integer;
    i:integer;
    FileNamePath:string;
begin
    Inc(counter);Label1.Caption:=inttostr(counter);
    if Msg.Message = WM_DROPFILES then
    begin
        DragQueryFile(Msg.wParam, 0, FileNames, Sizeof(FileNames) - 1);
        Files := DragQueryFile(Msg.wParam, $FFFFFFFF, nil, 0);
        if (FindDragTarget(Msg.pt,False) is TMemo) then
        begin
            for i := 0 to Files - 1 do
            begin
        DragQueryFile(Msg.wParam, i, FileNames, Sizeof(FileNames) - 1);
            FileNamePath:=StrPas(FileNames);
                memo1.Lines.Add(FileNamePath);
      end;
      end;
        DragFinish(Msg.wParam);
    end;
end;
//  最後に閉じられるフォームかをチェック
function IsLastForm(Form: TForm): Boolean;
var
    i     : Integer;
    AForm : TForm;
begin
    Result:= True;
    for i := 0 to Screen.FormCount-1 do begin
      AForm := Screen.Forms[I];
      if (AForm<>Form) and AForm.Visible and
         ((AForm.ParentWindow=0) or AForm.HandleAllocated or
         not IsChild(AForm.Handle,AForm.ParentWindow)) then begin
        Result := False;
        exit;
      end;
    end;
end;
//  このフォームが最後であればアプリケーションを終了
procedure TForm2.FormClose(Sender: TObject; var Action: TCloseAction);
begin
    if IsLastForm(Self) then Application.Terminate;
end;
//  フォーム表示時の処理
procedure TForm2.FormShow(Sender: TObject);
begin
    //アプリのウィンドウをタスクバーに表示しない
    ShowWindow(Application.Handle,SW_HIDE);
   if not NotFirstForm then begin
     NotFirstForm := True;
     //最初に表示するフォームはCmdShowに従う
     case CmdShow of
       SW_SHOWMINNOACTIVE: WindowState := wsMinimized;
       SW_SHOWMAXIMIZED:   WindowState := wsMaximized;
     end;
   end;
   Application.OnMessage:=  MsgHandler;     //-------------------D&Dを実現するため
   DragAcceptFiles(Memo1.Handle, True); //-------------------D&Dを実現するため
end;
//  つまりウィンドウの数だけアイコンが表示される
procedure TForm2.CreateParams(var Params: TCreateParams);
begin
    inherited;

    if FormStyle in [fsNormal, fsStayOnTop] then begin
      if BorderStyle in [bsSingle, bsSizeable] then begin
        Params.ExStyle := Params.ExStyle or WS_EX_APPWINDOW;
        Params.WndParent := 0;
      end;
    end;
end;
//新規作成
procedure TForm2.Button1Click(Sender: TObject);
begin
    Form1.CreateSubForm;
end;
//このフォームだけ閉じる
procedure TForm2.Button2Click(Sender: TObject);
begin
     Close;
end;
//全部のフォームを閉じる
procedure TForm2.Button3Click(Sender: TObject);
begin
     Application.Terminate;
end;
end.


tor  2014-02-27 18:45:06  No: 46085

ヲサヲサヲサヲサヲサチョマヘコスヲサヲサヘネサヲサヲサヲサヲサヲサッッュュュュュュュュュュュュュュュュュュュトヲサトを実現するため

チョマヘはアプリケーションに一つしかないのに、それを我も我もと上書きしているから一番最後に登録した人しか有効にならないんじゃないでしょうか。

かわりにフォームにヤチナを貼り付けて、そのマヘイベントを使うのはどうですか?
スススススススススススススススススススススススススススススススススススススススス
ニコ 宮
トコ イーアエッーイッイキィ木ゥ アイコエキコエカ  書込者ノト:ロ 」。ィ 。 ン

さんありがとうございます。
チナは使ったことがありませんので
いまからチナの使い方を調べて、
試してみます。
ありがとうございました。
スススススススススススススススススススススススススススススススススススススススス
ニコ 宮
トコ イーアエッーイッイキィ木ゥ アエコーーコアー  書込者ノト:ロ 」。ィ 。 ン
モコ 

さん、ご報告します。
うまくいきました。
サンプルを探し、ファイル毎に選別する必要がありますので
中を少し変更していますが間違った使い方をしている場合は、
注意していただければありがたいです。
ヲサヤニイョニモィモコヲサヤマゥサ

ョョョ
トチニィヘアョネャヲサヤゥサッッュュュュュュュュュュュュュュュュュュュトヲサトを実現するため

ヲサヤニイョチナアヘィヲサヘコヲサヘモヌサヲサネコヲサツゥサ

ヲサヲサヲサヲサニホコローョョイオオンヲサヲサテサ
ヲサヲサヲサヲサニヲサコノサ
ヲサヲサヲサヲサコサ
ヲサヲサヲサヲサニホミコサ

ヲサヲサヲサヲサヲサィヘョヲサスヲサヘアョネゥヲサヲサィヘョヲサスヲサラペトメマミニノフナモゥヲサ
ヲサヲサヲサヲサ
ヲサヲサヲサヲサヲサヲサヲサヲサニヲサコスヲサトムニィヘョラミャヲサ、ニニニニニニニニャヲサニホャヲサイオオゥサ
ヲサヲサヲサヲサヲサヲサヲサヲサヲサヲサコスヲサーヲサヲサニュアヲサ
ヲサヲサヲサヲサヲサヲサヲサヲサ
ヲサヲサヲサヲサヲサヲサヲサヲサヲサヲサヲサヲサトムニィヘョミャヲサャヲサニホャヲサモィニホゥヲサュヲサアゥサ
ヲサヲサヲサヲサヲサヲサヲサヲサヲサヲサヲサヲサニホミコスモミィニホゥサ
ヲサヲサヲサヲサヲサヲサヲサヲサヲサヲサヲサヲサアョフョチィニホミゥサ
ヲサヲサヲサヲサヲサヲサヲサヲササ
ヲサヲサヲサヲサヲサヲサヲサヲサトニィヘョラミゥサ
ヲサヲサヲサヲササ

チナがこんな働きをするとは、驚きです。勉強になりました。
お礼を申し上げます。では。


※返信する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






  このエントリーをはてなブックマークに追加