关于C++的几个问题

关于C++的几个问题,第1张

MFC 消息类型

1、命令消息(WM_COMMAND)

所有派生自 CCmdTarget 的类都有资格接受WM_COMMAND。

2、Window消息(WM_xxx)

所有派生自 CWnd 的类都有资格接受 WM_xxx。

3、控件消息(WM_NOTIFY)

控件向其父窗口通知消息。

消息处理

1、WM_xxx 消息处理

窗口类(自身)处理→基类处理→CWnd∷DefWindowProc()处理;

其所对应的宏一般为在消息 WM_ 前面加上 ON_。

2、命令消息处理

命令消息来自命令用户接口对象(菜单、加速键或工具栏按钮)发出的WM_COMMAND消息;

一、WM_COMMAND消息

其所包含的类型和对应的宏如下:

①、ON_COMMAND(ID,pfn)

标准的命令消息;

②、ON_COMMAND_EX(ID,pfn)

多个对象对同一个命令 ID 的处理;

函数的原型如下:

afx_msg BOOL pfn(UINT nID)

说明:

当返回 TRUE 时表示已经处理,不用在消息处理链中继续处理该命令;为 FALSE 时表示继续在消息处理链中处理该命令。

注意:

其一:在多对象处理中一定要使用该宏;

其二:pfn(UINT nID)(消息处理函数)返回值将其类型void改成BOOL,而且必须为FALSE;

其三:多个对象的处理是由高层向低层的过程:即视图类→主框架窗口类→应用程序类;

③、ON_COMMAND_RANGE(nID,nLastID,pfn)

多个命令 ID 提供相同的处理;

注意:

其一:确保nID、nLastID的值在 Resourceh 中是连续的。

其二:一般在函数 pfn(UINT nID) 中加入参数,用来确定那一个按钮点击。

二、CN_UPDATE_COMMAND_UI消息

当菜单项、工具栏按钮等[命令用户接口对象]要更新其状态时所对应的消息,它所包含的类型和对应的宏如下:

①、ON_UPDATE_COMMAND_UI(ID,pfn)

其中函数的原型如下:

afx_msg void pfn(CCmdUI pCmdUI)

②、ON_UPDATE_COMMAND_UI_RANGE(nID,nLastID,pfn)

该函数可以处理一组[命令用户接口对象]的外观;

其中函数的原型如下:

afx_msg void pfn(CCmdUI pCmdUI)

重要:

CCmdUI 中的 m_nID 成员表示不同的 ID,因此可以利用它来进行区别处理。

3、控件的通知消息

从控件和子窗口发送到父窗口的WM_COMMAND通知消息(即在发送命令消息中加入控件的通知码)。

注意:在 Window9x 新控件中不再传送WM_COMMAND通知消息,而是发送 WM_NOTIFY 消息,但为了兼容,旧有的控件还是传送WM_COMMAND消息。

例如:

CEdit控件向父窗口发送 EN_CHANGE 通知代码的WM_COMMAND消息。

注意:框架像传送其它 WM_ 消息一样传送通知消息,但有一个例外,即由 [按钮] 控件发送的 BN_CLICKED 通知消息,被作为命令消息特别处理。

一、WM_COMMAND 其所对应的宏如下:

①、ON_CONTROL(通知码, nID,fn)

②、ON_CONTROL_RANGE(通知码, nFirstID,nEndID,fn)

注意:

这两个宏的应用和 ON_COMMAND、ON_COMMAND_RANGE相同,所不同的是在宏前面加入[通知码]。

注意:可以根据不同的控件的[通知码]派生出特定的宏,其所派生的宏一般为在 [通知码] 前面加上 ON_。

二、WM_NOTIFY 其所对应的宏如下:

①、ON_NOTIFY(通知码, nID,fn)

其中函数的原型如下:

afx_msg void fn(NMHDR pNotifyStruct,LRESULT result)

其中结构:

typedef struct tagNMHDR {

HWND hwndFrom; //发送通知消息的控件的句柄;

UINT idFrom; //发送通知消息的控件的 ID;

UINT code; //通知码;

} NMHDR;

②、ON_NOTIFY_EX(通知码, nID,fn)

表示一个消息在多个对象的成员函数中进行处理。

其中函数的原型如下:

afx_msg BOOL fn(UINT nID,NMHDR pNotifyStruct,LRESULT result)

说明:

它必须返回 BOOL 类型的数值,其意义和 ON_COMMAND_EX 相同。

③、ON_NOTIFY_RANGE(通知码, nFirstID,nEnd,fn)

表示多个控件的通知消息在同一个函数中进行处理。

其中函数的原型如下:

afx_msg void fn(UINT nID,NMHDR pNotifyStruct,LRESULT result)

说明:

其意义和ON_COMMAND_RANGE相同。

4、反射消息处理

父窗口在处理控件窗口的通知消息WM_CTLCOLOR、WM_COMMAND、WM_NOTIFY时,会把该消息转化为反射消息,并转交给控件子窗口处理,只有在控件子窗体不处理该消息时,父窗口才有机会处理。

注意:在类的属性对话框中的消息页面可查反射消息(前面有"="标志)

①、WM_CTLCOLOR_REFLECT反射消息

其所对应的宏如下:

ON_WM_CTLCOLOR_REFLECT()

反射消息函数的原型:

HBRUSH class_name∷CtlColor(CDC pDC,UINT nCtlColor)

{

return NULL;

}

该函数用来重置控件的颜色;注意:必须 return CBrush才有效。

5、自定义的窗口消息

自定义窗口消息的消息标志都大于WM_USER(至少是WM_USER+100,因为许多控件都使用这一范围的WM_USER消息)

使用自定义的消息分为二步:

①、在 Resourceh 中定义消息标记

#define WM_MYMSG (WM_USER+1000)

②、在消息映射表中加入消息映射宏

BEGIN_MESSAGE_MAP()

ON_MESSAGE(WM_MYMSG,fn)

END_MESSAGE_MAP()

说明:

其对应的宏为 ON_MESSAGE(),其成员函数的原型为:

afx_msg LRESULT fn(WPARAM,LPARAM)

6、登记消息

①、在系统中注册并获取一个登记消息的消息标记

UINT RegisterWindowMessage(LPCTSTR)

说明:

通过 API 函数来注册消息标记,其中 LPCTSTR 为用户的任意字符串。例如:

UINT WM_MYMSG=RegisterWindowMessage("MYMSG");

其中 WM_MYMSG 是自定义无符号整型的消息标记。

②、在消息映射表中加入消息映射宏

BEGIN_MESSAGE_MAP()

ON_REGISTERED_MESSAGE(WM_MYMSG,fn)

END_MESSAGE_MAP()

说明:

其对应的宏为 ON_REGISTERED_MESSAGE(),其成员函数的原型为:

afx_msg LRESULT fn(WPARAM,LPARAM)

注意:登记消息可以实现跨进程的数据通讯。

7、线程消息

只有继承自CWinThread类才能允许处理线程消息。

①、定义线程的消息标记

有两种方法:

(1)、使用自定义的消息标记,即:WM_USER;

(2)、使用登记的消息标记,即:RegisterWindowMessage;

②、在CWinThread继承类的消息映射表中添加宏

ON_THREAD_MESSAGE(消息标记,fn) //自定义的消息;

ON_REGISTERED_THREAD_MESSAGE(消息标记,fn) //登记的 //消息

③、其函数的原型如下:

afx_msg void fn(WPARAM wPARAM,LPARAM lParam)

④、引发线程消息

线程消息的引发必须调用 CWinThread 类的PostThreadMessage将消息投递到线程消息队列中。

注意:可以通过 AfxGetApp() 函数获取一个全局的应用对象。

PostThreadMessage(UINT,WPARAM,LPARAM)

8、WM_COPYDATA

*** 作系统维护一块内存来管理 WM_COPYDATA 消息,该消息主要用于跨进程传递数据,传递的数据量达到 232。

①、定义一个 COPYDATASTRUCT 数据结构

typedef struct tagCOPYDATASTRUCT {

DWORD dwData; //自定义的特殊数据;

DWORD cbData; //以字节为单位的 lpData 的大小;

PVOID lpData; //传送的数据内存块的指针;

} COPYDATASTRUCT;

②、其所对应的宏

ON_WM_COPYDATA()

③、其所对应的函数的原型

afx_msg BOOL OnCopyData(CWnd,COPYDATASTRUCT)

说明:

CWnd:发送该消息的窗口的指针;

9、投递和发送消息

通过向一个窗体投递或发送消息,可以间接地驱动窗体的消息过程。

投递(PostMessage):将消息放到线程的消息队列中,然后不等线程处理该消息就直接返回到调用方。

发送(SendMessage):当一个线程向目标线程发送消息时,该线程要一直等待,直到目标线程处理了该消息为止。

①、投递消息

BOOL CWnd∷PostMessage(UINT,WPARAM=0,LPARAM=0)

说明:

CWnd:目标窗口;

该函数将一条消息放入到应用程序的消息队列,然后不等窗口处理就直接返回。

②、发送消息

LRESULT CWnd∷SendMessage(UINT,WPARAM=0,LPARAM=0)

说明:

CWnd:目标窗口;

该函数将一条消息放入到应用程序的消息队列,等待窗口处理后才返回。

为了避免线程陷入永久等待状态,可以用SendMessageTimeout代替SendMessage:

LRESULT SendMessageTimeout(HWND,UINT,WPARAM,LPARAM,UINT,UINT,PDWORD_PTR)

说明:

HWND:窗口句柄;

UINT:消息发送的选项,为SMTO_BLOCK时,可以防止线程无 限等待,即根据一定的超时值返回。

UINT:超时,以毫秒为单位;

PDWORD_PTR:返回值;

注意:CWnd没有对该函数的包装。

③、投递和发送消息

BOOL CWnd∷SendNotifyMessage(UINT,WPARAM,LPARAM)

说明:

CWnd:目标窗口;

该消息具有SendMessage和PostMessage两种功能:

当目标窗口和发送窗口为同一个线程时,则相当于SendMessage的功能;否则当不为同一个线程时,则为PostMessage的功能。

6-1、投递和发送 WM_XXX 消息

在发送标准的 WINDOW 消息时,只要将该消息的 ID、wParam、lParam参数放在 SendMessage()和PostMessage()函数的相应位置即可。

6-2、投递和发送命令消息和控件的通知消息

在投递和发送命令消息时,消息的 ID为 WM_COMMADN,而对于不同的菜单项、加速键、控件则wParam、lParam的取值不同。

wParam分成低、高两部分,低部分为菜单项、加速键、控件的ID。高部分则:

菜单项:0;加速键:1;控件:通知码

lParam:当控件时是控件的句柄,否则为 NULL。

对于wParam参数可以采用自定义宏:

WPARAM MAKEWPARAM(WORD wLow,WORD wHigh)

6-3、投递和发送自定义的窗口消息

在投递和发送自定义的窗口消息时,参数 wParam、lParam 没有特别的涵义,只和普通函数的形参一样进行数据的传递。

注意:

PostMessage 和 SendMessage 是不同的,前者投递后就返回,而后者必须等到消息处理后再返回;所以在参数是 [局部] 或 [临时]时,使用PostMessage函数会引发错误(除非参数使用 指针,则可避免错误),而必须使用SendMessage函数。

6-4、投递和发送注册的窗口消息

和 6-3 基本一样,但它要特别注意的问题是:在跨进程的处理消息时,如果将消息PostMessage、SendMessage到某个进程 A,则必须在进程 B 中获取进程 A 的窗口类名,并通过窗口类名获取窗口的指针,最后再根据指针调用 PostMessage、SendMessage 函数。

注意:在获取窗口的指针时,可以根据窗口类名或窗口的标题。

6-5、投递和发送WM_COPYDATA消息

SendMessage(消息标记,WPARAM,LPARAM)

其中:

消息标记:WM_COPYDATA;

WPARAM:发送该消息的窗口句柄;

LPARAM:COPYDATASTRUCT结构的指针,先通过(LPVOID)进行转换,再通过(LPARAM)进行转换,如下形式:

(LPARAM)(LPVOID)&cds

用户自定义消息代码

映射入口 函数原型

ON_MESSAGE(<message>,<FUN>) afx_msg LONG FUN(UINT wparam,LONG lparam);

ON_REGISTERED_MESSAGE(<nMessageVariable>,<FUN>) afx_msg LONG FUN(UINT wparam,LONG lparam);

MeMousePointer = 99

MeMouseIcon = LoadPicture("c:\123ico")

贴主不会追问

如果要问详细点的话,另请高明

Java中的鼠标和键盘事件

使用MouseListener借口处理鼠标事件

鼠标事件有 种 按下鼠标键 释放鼠标键 点击鼠标键 鼠标进入和鼠标退出

鼠标事件类型是MouseEvent 主要方法有

getX() getY() 获取鼠标位置

getModifiers() 获取鼠标左键或者右键

getClickCount() 获取鼠标被点击的次数

getSource() 获取鼠标发生的事件源

事件源获得监视器的方法是addMouseListener() 移去监视器的方法是removeMouseListener()

处理事件源发生的时间的事件的接口是MouseListener 接口中有如下的方法

mousePressed(MouseEvent) 负责处理鼠标按下事件

mouseReleased(MouseEvent) 负责处理鼠标释放事件

mouseEntered(MouseEvent) 负责处理鼠标进入容器事件

mouseExited(MouseEvent) 负责处理鼠标离开事件

mouseClicked(MouseEvent) 负责处理点击事件

使用MouseMotionListener接口处理鼠标事件

事件源发生的鼠标事件有 种 拖动鼠标和鼠标移动

鼠标事件的类型是MouseEvent

事件源获得监视器的方法是addMouseMotionListener()

处理事件源发生的事件的接口是MouseMotionListener 接口中有如下的方法

mouseDragged() 负责处理鼠标拖动事件

mouseMoved() 负责处理鼠标移动事件

控制鼠标的指针形状

setCursor(Cursor getPreddfinedCursor(Cursor 鼠标形状定义)) 鼠标形状定义见(书 P )

键盘事件

键盘事件源使用addKeyListener 方法获得监视器

键盘事件的接口是KeyListener 接口中有 个方法

public void keyPressed(KeyEvent e) 按下键盘按键

public void keyReleased(KeyEvent e) 释放键盘按键

public void keyTypde(KeyEvent e) 按下又释放键盘按键

package mouseenvent;

import java awt ;

import javax swing ;

import java awt event ;

public class Mouse extends JFrame implements MouseListener{

JPanel jp = new JPanel();

JLabel statu ar = new JLabel();

static final long serialVersionUID= ;

public Mouse(){

setTitle( Mouse Event );

getContentPane() add(jp BorderLayout CENTER);

getContentPane() add(statu ar BorderLayout SOUTH);

jp addMouseListener(this);

}

public static void main(String[] args){

Mouse frame = new Mouse();

frame setSize( );

frame setVisible(true);

frame setDefaultCloseOperation(JFrame EXIT_ON_CLOSE);

}

public void mousePressed(MouseEvent e){

int x = e getX();

int y = e getY();

String s = 鼠标在坐标 + ( +x+ +y+ ) + 处按下 ;

statu ar setText(s);

}

public void mouseReleased(MouseEvent e){

int x = e getX();

int y = e getY();

String s = 鼠标在坐标 + ( +x+ +y+ ) + 处释放 ;

statu ar setText(s);

}

public void mouseClicked(MouseEvent e){

int x = e getX();

int y = e getY();

String s = 鼠标在坐标 + ( +x+ +y+ ) + 处点击 ;

statu ar setText(s);

}

public void mouseEntered(MouseEvent e){

int x = e getX();

int y = e getY();

String s = 鼠标在坐标 + ( +x+ +y+ ) + 处进入 ;

statu ar setText(s);

}

public void mouseExited(MouseEvent e){

int x = e getX();

int y = e getY();

String s = 鼠标在坐标 + ( +x+ +y+ ) + 处离开 ;

statu ar setText(s);

}

}

package mouseenvent;

import java awt ;

import javax swing ;

import java awt event ;

public class MouseMotion extends JFrame implements MouseMotionListener{

static final long serialVersionUID= ;

JLabel bar = new JLabel();

JTextField text = new JTextField();

public MouseMotion(){

setTitle( Mouse Event );

getContentPane() add(text BorderLayout NORTH);

getContentPane() add(bar BorderLayout SOUTH);

addMouseMotionListener(this);

}

public void mousePressed(MouseEvent e){

int x = e getX();

int y = e getY();

String s = x = +x+ y = +y;

bar setText(s);

text setText(s);

}

public void mouseDragged(MouseEvent e){

int x = e getX();

int y = e getY();

String s = x = +x+ y = +y;

bar setText(s);

text setText(s);

}

public void mouseMoved(MouseEvent e){

int x = e getX();

int y = e getY();

String s = x = +x+ y = +y;

bar setText(s);

text setText(s);

}

public static void main(String args[])throws Exception{

MouseMotion mouse = new MouseMotion();

mouse setSize( );

mouse setVisible(true);

mouse setDefaultCloseOperation(JFrame EXIT_ON_CLOSE);

}

}

package mouseenvent;

import java awt event ;

import javax swing ;

import java awt ;

public class Key extends JFrame implements KeyListener{

JLabel bar ;

public Key(){

bar = new JLabel();

getContentPane() add(bar BorderLayout CENTER);

addKeyListener(this);

}

public void keyPressed(KeyEvent e){

char c = e getKeyChar();

String s = c+ ;

bar setText(s);

}

public void keyReleased(KeyEvent e){

char c = e getKeyChar();

}

public void keyTyped(KeyEvent e){

char c = e getKeyChar();

}

public static void main(String args[])throws Exception{

Key key = new Key();

key setSize( );

key setVisible(true);

key setDefaultCloseOperation(JFrame DISPOSE_ON_CLOSE);

}

lishixinzhi/Article/program/Java/hx/201311/25830

以上就是关于关于C++的几个问题全部的内容,包括:关于C++的几个问题、怎么弄窗口中的指针、Java获取窗口鼠标坐标以及键盘按键等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/web/9598100.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2023-04-30
下一篇2023-04-30

发表评论

登录后才能评论

评论列表(0条)

    保存