Delphi Programming / Object Pascal
[掲載 2005年02月26日] [更新 2012年04月11日] Delphi サンプルプログラム集 |
120_SC_DRAGMOVE コマンドによるコントロールのドラッグ |
動作確認等 |
Windows XP(SP3) + Delphi XE Pro
Windows 7 U64(SP1) + Delphi XE Pro |
|
120_ControlDrag3.zip [843 KB] 2012年04月11日版 (EXE 同梱) |
- 2012年04月11日
- Delphi XE での動作確認とコードと記事の整備
|
01_SC_DRAGMOVE コマンドでコントロールをドラッグ開始 |
ウィンドウをドラッグすると,システムの SC_DRAGMOVE コマンドが発行されます.逆にこのコマンドをドラッグ対象のウィンドウに対して送ると,ドラッグできることになります.
このコマンドは,WM_SYSCOMMAND メッセージのパラメータとして送ります.ウィンドウに対してメッセージを送りますから,この方法は,ウィンドウハンドルを持たない,TImage 等,TGraphicControl の派生コンポーネントでは使用できません.TWinControl 専用です. |
旧Delphi FAQ - VCL(2) の [マウスでコンポーネント (たとえば、TPanel) を実行時にドラッグ] に次のようなサンプルコードがあります.このコードでドラッグを開始できます. |
procedure TForm1.Panel1MouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
const
SC_DRAGMOVE = $F012;
begin
ReleaseCapture;
TWinControl(Sender).Perform(WM_SYSCOMMAND, SC_DRAGMOVE, 0);
end;
上のコードでは,MouseUp イベントを捕らえることができません.そのため,このコード内でマウスカーソルの形状を変更した場合,ローカルフック等で MouseUp を捕らえて変更する必要があります.その対策をしたのが次のコードです.TChart も移動可能でしたので,ついでに TChart の一部をコードで設定してみました. |
|
図1
実行開始画面
- 以下のコントロールを配置
TBitBtn
TButton
TPanel
TScrollBox
TCheckListBox
TChart (TBarSeries)
- TChart の一部をコードで設定している
|
|
図2
TChart をドラッグ中
- Windows XP では,ドロップすると,そのコントロールが最前面に来てしまう
- 元の Z オーダにするには対策が必要
- この仕様がいい場合もあるかも知れない
|
リスト2
SC_DRAGMOVE コマンドでコントロールをドラッグ開始 |
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls, ExtCtrls, Buttons, CheckLst, TeeProcs, TeEngine, Chart, Grids,
AppEvnts, Series,XPMan;
type
TForm1 = class(TForm)
BitBtn1: TBitBtn;
Button1: TButton;
Panel1: TPanel;
ScrollBox1: TScrollBox;
CheckListBox1: TCheckListBox;
Chart1: TChart;
Series1: TBarSeries;
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
procedure Panel1MouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
private
{ Private 宣言 }
public
{ Public 宣言 }
end;
var
Form1: TForm1;
implementation
{$R *.DFM}
var
HookHandle : HHOOK;
AControl : TWinControl;
//=============================================================================
// WH_GETMESSAGEフックのコールバック関数
// ここではマウスの左ボタンが離された時だけ処理
// ローカルフックについてはHalbow資料館を参考
//=============================================================================
function GetMsgProc(Code: Integer; wParam: wParam; lParam:lParam): LRESULT; stdcall;
var
Msg : PMsg;
begin
if (Code < 0) then begin
Result := CallNextHookEx(HookHandle, Code, wParam, lParam);
exit;
end;
if (Code = HC_ACTION) then begin
Msg := PMsg(lParam);
case Msg^.message of
WM_LBUTTONUP:
begin
if wParam = PM_REMOVE then begin
if AControl <> nil then AControl.Cursor := crDefault;
end;
end;
end;
end;
Result := CallNextHookEx(HookHandle, Code, wParam, lParam);
end;
//=============================================================================
// FormのCreate時
// ローカルフック開始
// TChartもこのPerformで移動可能なのでついでに,TChartの一部分の設定をコード
// で行ってみた
// TChartは設計時に棒グラフを作成してある
//=============================================================================
procedure TForm1.FormCreate(Sender: TObject);
begin
Series1.Clear;
Randomize;
//タイトル
Chart1.Title.Text.Clear;
Chart1.Title.Text.Add('棒グラフの例');
//棒グラフの棒の色
Series1.SeriesColor := $005BA466;
//データ
Series1.Add(Random(50), 'A');
Series1.Add(Random(50), 'B');
Series1.Add(Random(50), 'C');
Series1.Add(Random(50), 'D');
//縦軸の設定
Chart1.LeftAxis.Automatic := False;
Chart1.LeftAxis.Maximum := 50;
Chart1.LeftAxis.Increment := 10;
Chart1.LeftAxis.TickLength := 0;
Chart1.LeftAxis.MinorTickCount := 1;
Chart1.LeftAxis.MinorTickLength := -5;
//横軸の設定
Chart1.BottomAxis.Grid.Visible := False;
Chart1.BottomAxis.Ticks.Visible := False;
Chart1.BottomAxis.MinorTicks.Visible := False;
HookHandle := SetWindowsHookEx(WH_GETMESSAGE, GetMsgProc, 0, GetCurrentThreadID);
end;
//=============================================================================
// ローカルフック解除
//=============================================================================
procedure TForm1.FormDestroy(Sender: TObject);
begin
UnHookWindowsHookEx(HookHandle);
end;
//=============================================================================
// コントロール上でマウスをクリックしたらドラッグ開始
//=============================================================================
procedure TForm1.Panel1MouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
const
SC_DRAGMOVE = $F012;
begin
ReleaseCapture;
AControl := TWinControl(Sender);
AControl.Cursor := crSizeAll;
AControl.Perform(WM_SYSCOMMAND, SC_DRAGMOVE, 0);
end;
end.
|