加载中…
个人资料
  • 博客等级:
  • 博客积分:
  • 博客访问:
  • 关注人气:
  • 获赠金笔:0支
  • 赠出金笔:0支
  • 荣誉徽章:
正文 字体大小:

GetMessage函数的用法

(2007-11-25 16:32:22)
标签:

知识/探索

分类: 学习笔记
 Win32 API消息函数:GetMessage

    函数功能:该函数从调用线程的消息队列里取得一个消息并将其放于指定的结构。此函数可取得与指定窗口联系的消息和由PostThreadMesssge寄送的线程消息。此函数接收一定范围的消息值。GetMessage不接收属于其他线程或应用程序的消息。

    函数原型:BOOL GetMessage(LPMSG lpMsg,HWND hWnd,UINT wMsgFilterMin,UINT wMsgFilteMax

    参数:

    lpMsg:指向MSG结构的指针,该结构从线程的消息队列里接收消息信息。

    hWnd:取得其消息的窗口的句柄。这是一个有特殊含义的值(NULL)。GetMessage为任何属于调用线程的窗口检索消息,线程消息通过PostThreadMessage寄送给调用线程。

    wMsgFilterMin:指定被检索的最小消息值的整数。

    wMsgFilterMax:指定被检索的最大消息值的整数。

    返回值:如果函数取得WM_QUIT之外的其他消息,返回非零值。如果函数取得WM_QUIT消息,返回值是零。如果出现了错误,返回值是_1。例如,当hWnd是无效的窗口句柄或lpMsg是无效的指针时。若想获得更多的错误信息,请调用GetLastError函数。

    备注:应用程序通常用返回值来确定是否终止主消息循环并退出程序。

    GetMesssge只接收与参数hWnd标识的窗口或子窗口相联系的消息,子窗口由函数IsChild决定,消息值的范围由参数wMsgFilterMin和wMsgFilterMax给出。如果hWnd为NULL,则GetMessage接收属于调用线程的窗口的消息,线程消息由函数PostThreadMessage寄送给调用线程。GetMessage不接收属于其他线程或其他线程的窗口的消息,即使hWnd为NULL。由PostThreadMessage寄送的线程消息,其消息hWnd值为NULL。如果wMsgFilterMin和wMsgFilterMax都为零,GetMessage返回所有可得的消息(即,无范围过滤)。

    常数 WM_KEYFIRST和WM_KEYAST可作为过滤值取得与键盘输入相关的所有消息:常数WM_MOUSEFIRST和WM_MOUSELST可用来接收所有的鼠标消息。如果wMsgFilterMin和wMsgFilterMax都为零,GetMessage返回所有可得的消息(即,无范围过滤)。

    GetMessage不从队列里清除WM.PAINT消息。该消息将保留在队列里直到处理完毕。

    注意,此函数的返回值可非零、零或-1,应避免如下代码出现:

    while(GetMessage(IpMsg,hwnd,0,0))…

    -1返回值的可能性表示这样的代码会导致致命的应用程序错误。
 

下面是使用GetMessage的例子

unit Unit4;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs,DBTables, Db, ADODB, Grids, DBGrids, StdCtrls, Buttons;
const
WM_OPENDATASET = WM_USER + 1;
WM_EXECUTESQL = WM_USER  + 2;
type
TThreadDataSet = class(TThread)
  private
    procedure WMOpenDataSet(Msg: TMsg);
    procedure WMExecSQL(Msg: TMsg);
  protected
    procedure Execute; override;
  public
    procedure Open(DataSet: TDataSet);
    procedure ExecSQL(DataSet: TDataSet);
end;

  TForm4 = class(TForm)
    ADOTable1: TADOTable;
    ADOQuery1: TADOQuery;
    DataSource1: TDataSource;
    DBGrid1: TDBGrid;
    DBGrid2: TDBGrid;
    DataSource2: TDataSource;
    BitBtn1: TBitBtn;
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
    procedure BitBtn1Click(Sender: TObject);
  private
    { Private declarations }
    FThread : TThreadDataSet;
  public
    { Public declarations }
  end;

var
  Form4: TForm4;

implementation

{$R *.dfm}
uses ActiveX;

procedure TThreadDataSet.ExecSQL(DataSet: TDataSet);
begin
  PostThreadMessage(ThreadID, WM_EXECUTESQL, Integer(DataSet), 0);
end;

procedure TThreadDataSet.Execute;
var
  Msg : TMsg;
begin
  CoInitialize(nil);
try
  FreeOnTerminate := True;
  PeekMessage(Msg, 0, WM_USER, WM_USER, PM_NOREMOVE);
  while not Terminated do
  begin

     if GetMessage(msg,0,0,0) then
     begin
      case Msg.Message of
       WM_OPENDATASET: WMOpenDataSet(Msg);
       WM_EXECUTESQL: WMExecSQL(Msg);
      end;
     end;
  end;
finally
   CoUninitialize;
end;
end;

procedure TThreadDataSet.Open(DataSet: TDataSet);
begin
  PostThreadMessage(ThreadID, WM_OPENDATASET, Integer(DataSet), 0);
end;

procedure TThreadDataSet.WMExecSQL(Msg: TMsg);
var
  Qry : TQuery;
begin
try
  Qry := TQuery(Msg.wParam);
  try
   Qry.Open;
  except
   Qry.ExecSQL;
  end;
except
  On E: Exception do
    ShowMessage(E.Message);
end;
end;

procedure TThreadDataSet.WMOpenDataSet(Msg: TMsg);
var
 Ds : TDataSet;
begin
try
 Ds := TDataSet(Msg.wParam);
 Ds.Open;
except
 On E: Exception do ShowMessage(E.Message);
end;
end;

procedure TForm4.FormCreate(Sender: TObject);
begin
  FThread := TThreadDataSet.Create(False);
end;

procedure TForm4.FormDestroy(Sender: TObject);
begin
FThread.Terminate;
end;

procedure TForm4.BitBtn1Click(Sender: TObject);
begin
  FThread.Open(ADOTable1); // Opening a dataset (table or query)
  FThread.ExecSQL(ADOQuery1); // Executing a SQL

end;

end.

 

 

 

 


0

阅读 收藏 喜欢 打印举报/Report
  

新浪BLOG意见反馈留言板 欢迎批评指正

新浪简介 | About Sina | 广告服务 | 联系我们 | 招聘信息 | 网站律师 | SINA English | 产品答疑

新浪公司 版权所有