分类: WINDOWS
2010-08-24 10:15:38
实例目标
实现左边标题,能拖动的窗口。如下图所示:
实现技术
第一步先指明窗口BorderStyle 为bsNone,这样就不能拉伸窗,没有标题和边框。第二
步就是在FormPaint(TObject *Sender) 函数里面画上标题和边框。这个函数响应消息OnPaint,
当出现重画窗口时调用。第三步就是响应WM_NCHITTEST 消息,以便拖动窗口。当返回
这个消息的结果为HTCAPTION 时,WINDOWS 就认为鼠标在标题框内,所以能拖动窗口
移动。
实现步骤
第一步创建程序,在Object Inspector 中设置BorderStyle 为bsNone 。
第二步添加DrawTitle() ,代码如下:
void __fastcall TfrmTitle::DrawTitle(void)
{
RECT rc;
//左边标题栏。
::SetRect(&rc,0,0,nTitleWidth,ClientHeight);
Canvas->Brush->Color = clBlue;
Canvas->FillRect(rc);
//右边边界。
::SetRect(&rc,ClientWidth-2,0,ClientWidth,ClientHeight);
Canvas->Brush->Color = clBlue;
Canvas->FillRect(rc);
//上面边界。
::SetRect(&rc,0,0,ClientWidth,2);
Canvas->Brush->Color = clBlue;
Canvas->FillRect(rc);
//下面边界。
::SetRect(&rc,0,ClientHeight-2,ClientWidth,ClientHeight);
Canvas->Brush->Color = clBlue;
Canvas->FillRect(rc);
//设置ICON 位置。
ImageIcon->Left = 0;
ImageIcon->Top = ClientHeight - ImageIcon->Height;
//输出标题。
char* msg=Caption.c_str();
LOGFONT fontRec;
memset(&fontRec,0,sizeof(LOGFONT));
fontRec.lfHeight = -13;
fontRec.lfWeight = FW_NORMAL;
fontRec.lfEscapement = 900; // 字体旋转90 度。
lstrcpy(fontRec.lfFaceName," 宋体");
HFONT hFont=CreateFontIndirect(&fontRec);// 创建字体。
HFONT hOld=::SelectObject(Canvas->Handle,hFont);// 选中字体。
::SetRect(&rc,0,0,nTitleWidth,ClientHeight);
::SetTextColor(Canvas->Handle,RGB(255,255,255));// 设置字体的颜色。
//输出标题。
::TextOut(Canvas->Handle,3,ClientHeight - ImageIcon->Height,msg,lstrlen(msg));
::SelectObject(Canvas->Handle,hOld);// 恢复。
::DeleteObject(hFont);
}
第三步添加OnNcHitTest(TMessage& tMsg) 函数,处理WM_NCHITTEST 消息。
void TfrmTitle::OnNcHitTest(TMessage& tMsg)
{
TPoint pt;
//取得鼠标位置。
pt.x=LOWORD(tMsg.LParam);
pt.y=HIWORD(tMsg.LParam);
pt =ScreenToClient(pt);// 转换为客户坐标。
RECT rc;
::SetRect(&rc,0,0,nTitleWidth,ClientHeight);
if(PtInRect(&rc,pt))// 是否在自画的标题框内。
tMsg.Result = HTCAPTION;// 返回在标题栏内结果。
else
DefaultHandler(&tMsg);// 让窗口缺省消息处理函数处理。
}
源程序本地下载:
|
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, ExtCtrls, StdCtrls, Menus;
type
TForm1 = class(TForm)
Panel1: TPanel;
MainMenu1: TMainMenu;
mnuFile: TMenuItem;
private
procedure MyMsg(var msg: TWMNCHitTest); message WM_NCHITTEST;
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
const
arr: array[-2..21] of string = (
'HTERROR',
'HTTRANSPARENT',
'HTNOWHERE',
'HTCLIENT - 客户区',
'HTCAPTION - 标题',
'HTSYSMENU - 系统菜单',
'HTGROWBOX',
'HTMENU - 菜单',
'HTHSCROLL - 水平滚动条',
'HTVSCROLL - 垂直滚动条',
'HTMINBUTTON - 最小化按钮',
'HTMAXBUTTON - 最大化按钮',
'HTLEFT - 左边界',
'HTRIG - 右边界',
'HTTOP - 上边界',
'HTTOPLEFT - 左上角',
'HTTOPRIG - 右上角',
'HTBOTTOM - 下边界',
'HTBOTTOMLEFT - 左下角',
'HTBOTTOMRIG - 右下角',
'HTBORDER',
'HTOBJECT',
'HTCLOSE - 关闭按钮',
'HTHELP');
procedure TForm1.MyMsg(var msg: TWMNCHitTest);
var
i: Integer;
begin
Inherited;
i := msg.Result;
Text := Format('%d: %s', [i, arr[i]]);
end;
end.
//另附 WM_NCHITTEST 消息中 Result 参数的所有可能值的列表:
HTERROR = -2;
HTTRANSPARENT = -1;
HTNOWHERE = 0;
HTCLIENT = 1;
HTCAPTION = 2;
HTSYSMENU = 3;
HTGROWBOX = 4;
HTSIZE = HTGROWBOX;
HTMENU = 5;
HTHSCROLL = 6;
HTVSCROLL = 7;
HTMINBUTTON = 8;
HTMAXBUTTON = 9;
HTLEFT = 10;
HTRIGHT = 11;
HTTOP = 12;
HTTOPLEFT = 13;
HTTOPRIGHT = 14;
HTBOTTOM = 15;
HTBOTTOMLEFT = $10;
HTBOTTOMRIGHT = 17;
HTBORDER = 18;
HTREDUCE = HTMINBUTTON;
HTZOOM = HTMAXBUTTON;
HTSIZEFIRST = HTLEFT;
HTSIZELAST = HTBOTTOMRIGHT;
HTOBJECT = 19;
HTCLOSE = 20;
HTHELP = 21;