请教: perform(messageid,wparam,lparam):longint;返回的是什么?(150分)

  • 主题发起人 主题发起人 rove11
  • 开始时间 开始时间
R

rove11

Unregistered / Unconfirmed
GUEST, unregistred user!
大虾:
如:perform(em_linefromchar,-1,0);
返回的是行坐标。

那么:
perform(messageid,wparam,lparam):longint;
sendmessage(hwnd;msg,wparam,lparam):lresult;
如果他们带的是各种别的消息,返回的是什么呢?
wparam,lparam 又是怎样设定的。

请把消息分得详细点讲解。
 
sendMessage
将一条消息投递到指定窗口的消息队列。投递的消息会在Windows事件处理过程中得到处理。
返回值
Long,如消息投递成功,则返回TRUE(非零)。
参数
hwnd Long,接收消息的那个窗口的句柄。如设为HWND_BROADCAST,表示投递
给系统中的所有顶级窗口。如设为零,表示投递一条线程消息
wMsg Long, 消息标识符
wParam Long, 具体由消息决定
lParam Any, 具体由消息决定
具体就看看帮助和MSDN.
 
TO ZRWeng
先谢您了!

问题是我就想要知道“具体”的情况。
是不是可以把消息分成几大部分来讲解呢?
 
我建议你看看书,任何一本windows开发的书对消息的原理,实现讲的都很详细的。
 
那么VCL中的PERFORM()呢????????
 
看看源码,它调用的还是sendmessage
 
function TControl.Perform(Msg: Cardinal; WParam, LParam: Longint): Longint;
var
Message: TMessage;
begin
Message.Msg := Msg;
Message.WParam := WParam;
Message.LParam := LParam;
Message.Result := 0;
if Self <> nil then WindowProc(Message);
Result := Message.Result;
end;
可见,Perform返回的是Message的Result
 
Message.Result是由函数自己定义的,随便是什么值都可以
比如我有一个过程,相应某消息,Message.Result:=34567,任意值都可以。
你说的
perform(em_linefromchar,-1,0);
返回的是行坐标。
这是因为执行perform的控件自己的消息处理过程把行坐标赋值给了Message.Result
 
对了,你说的EM_LINEFROMCHAR消息,是windows内部实现的:
function TCustomMemo.GetCaretPos: TPoint;
begin
Result.X := LongRec(SendMessage(Handle, EM_GETSEL, 0, 0)).Hi;
Result.Y := SendMessage(Handle, EM_LINEFROMCHAR, Result.X, 0);
Result.X := Result.X - SendMessage(Handle, EM_LINEINDEX, -1, 0);
end;
这样一些就比较特殊了,返回值是windows确定的,
因为TCustomMemo的具体实现是windows完成的
 
谢谢:
TO DEVIL—LI
a: 那么我把消息可分成如下几个部分吗?还有别的没有?
1:WINDOWS内部定义的:EM-
2:WINDOWS标准消息:WM-
3:VCL 内部消息:CM-
4:WINDOWS标准的控件消息:BN-

b: 在DELPHI中,是否只有第1:部分需由WINDOWS内部处理?(比较特殊的)

c: 如:TCustomMemo, 还有那些是由WINDOWS具体实现的?

TO Shangshang
"看看源码,它调用的还是sendmessage"
在什么地方?请贴一下原码好吗?
 
这里是Perform方法的源代码
[red]
function TControl.Perform(Msg: Cardinal; WParam, LParam: Longint): Longint;
var
Message: TMessage;//定义消息为TMessage结构
begin
Message.Msg := Msg;//填入你的消息标识到TMessage的Msg域
Message.WParam := WParam;
Message.LParam := LParam;//参数与TMessage消息参数一样,说明Perform还是将消息翻译为TMessage来处理的
Message.Result := 0;//返回值为0,即没有处理
if Self <> nil then WindowProc(Message);//这里是关键!将消息交给TControl的窗口过程(WindowProc)处理
Result := Message.Result;
end;
----------------------------------------
property WindowProc: TWndMethod read FWindowProc write FWindowProc;
//这里说明了WindowProc作为TControl的一个属性,依靠TWndMethod类型的变量FWindowProc来读写
constructor TControl.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
FWindowProc := WndProc;
....
//这里说明在组件创建的时候将WndProc写入变量FWindowProc 中
procedure WndProc(var Message: TMessage); virtual;
//这里说明WndProc(var Message: TMessage)方法是个虚拟的方法,可以自己重载!
TWinControl = class(TControl)
..
procedure WndProc(var Message: TMessage);Override;//在TWinControl重载TControl的同名方法
下面就是追到的处理部分了
TControl的处理部分
procedure TControl.WndProc(var Message: TMessage);
var
Form: TCustomForm;
KeyState: TKeyboardState;
WheelMsg: TCMMouseWheel;
begin
if (csDesigning in ComponentState) then
begin
Form := GetParentForm(Self);
if (Form <> nil) and (Form.Designer <> nil) and
Form.Designer.IsDesignMsg(Self, Message) then Exit
end;
if (Message.Msg >= WM_KEYFIRST) and (Message.Msg <= WM_KEYLAST) then
begin
Form := GetParentForm(Self);
if (Form <> nil) and Form.WantChildKey(Self, Message) then Exit;
end
else if (Message.Msg >= WM_MOUSEFIRST) and (Message.Msg <= WM_MOUSELAST) then
begin
if not (csDoubleClicks in ControlStyle) then
case Message.Msg of
WM_LBUTTONDBLCLK, WM_RBUTTONDBLCLK, WM_MBUTTONDBLCLK:
Dec(Message.Msg, WM_LBUTTONDBLCLK - WM_LBUTTONDOWN);
end;
case Message.Msg of
WM_MOUSEMOVE: Application.HintMouseMessage(Self, Message);
WM_LBUTTONDOWN, WM_LBUTTONDBLCLK:
begin
if FDragMode = dmAutomatic then
begin
BeginAutoDrag;//拖放
Exit;
end;
Include(FControlState, csLButtonDown);
end;
WM_LBUTTONUP:
Exclude(FControlState, csLButtonDown);
else
with Mouse do
if WheelPresent and (RegWheelMessage <> 0) and
(Message.Msg = RegWheelMessage) then
begin
GetKeyboardState(KeyState);
with WheelMsg do
begin
Msg := Message.Msg;
ShiftState := KeyboardStateToShiftState(KeyState);
WheelDelta := Message.WParam;
Pos := TSmallPoint(Message.LParam);
end;
MouseWheelHandler(TMessage(WheelMsg));
Exit;
end;
end;
end
else if Message.Msg = CM_VISIBLECHANGED then
with Message do
SendDockNotification(Msg, WParam, LParam);
Dispatch(Message);//发送消息
end;
TWinControl重载后新加的处理部分
procedure TWinControl.WndProc(var Message: TMessage);
var
Form: TCustomForm;
begin
case Message.Msg of
WM_SETFOCUS:
begin
Form := GetParentForm(Self);
if (Form <> nil) and not Form.SetFocusedControl(Self) then Exit;
end;
WM_KILLFOCUS:
if csFocusing in ControlState then Exit;
WM_NCHITTEST:
begin
inherited WndProc(Message);//先重载父类的方法
if (Message.Result = HTTRANSPARENT) and (ControlAtPos(ScreenToClient(
SmallPointToPoint(TWMNCHitTest(Message).Pos)), False) <> nil) then
Message.Result := HTCLIENT;
Exit;
end;
WM_MOUSEFIRST..WM_MOUSELAST:
if IsControlMouseMsg(TWMMouse(Message)) then
begin
{ Check HandleAllocated because IsControlMouseMsg might have freed the
window if user code executed something like Parent := nil. }
if (Message.Result = 0) and HandleAllocated then
DefWindowProc(Handle, Message.Msg, Message.wParam, Message.lParam);
Exit;
end;
WM_KEYFIRST..WM_KEYLAST:
if Dragging then Exit;
WM_CANCELMODE:
if (GetCapture = Handle) and (CaptureControl <> nil) and
(CaptureControl.Parent = Self) then
CaptureControl.Perform(WM_CANCELMODE, 0, 0);
end;
inherited WndProc(Message);
end;
关键的都在这里了,你自己去看看吧
[/red]
这些代码都是Controls.pas单元中的,位置在X:/../Borland/Delphi6/Source/Vcl中
的Controls文件。自己找,看看对你消化消息处理由很大作用的!
 
to:晶晶
研究得透彻,佩服!
 
多人接受答案了。
 

Similar threads

S
回复
0
查看
3K
SUNSTONE的Delphi笔记
S
S
回复
0
查看
2K
SUNSTONE的Delphi笔记
S
后退
顶部