用户
搜索

该用户从未签到

i春秋作家

Rank: 7Rank: 7Rank: 7

16

主题

27

帖子

249

魔法币
收听
0
粉丝
0
注册时间
2018-1-1

i春秋签约作者

发表于 6 天前 62087
本帖最后由 flag0 于 2020-7-30 11:36 编辑

本文原创作者flag0,本文属于i春秋原创奖励计划,未经许可禁止转载!

发送消息

手动向窗口发消息。

向窗口发送消息

PostMessage:会把消息投递到消息队列。

SendMessage:会直接调用窗口过程函数。

PostMessage(hWnd, WM_KEYDOWN, 'a', 0);

发送自定义消息

为了区分系统的消息和自定义的消息,windows提供了WM_USER宏。

#define WM_USER 0x0400

系统的消息都是在0x400以下,所以自定义消息,要在400以上,才能不和系统消息来进行冲突。

例:#define WM_MYMSG WM_USER+1

//发送消息
SendMessage(hWnd, WM_MYMSG, 0, 0);
//在窗口过程函数内处理消息
case WM_MYMSG:
{
    MessageBox(hwnd, "WM_MYMSG", NULL, NULL);
    return 0;
}

对话框

系统预定义好的窗口类,叫做控件,例如BUTTONCOMBOBOXLISTBOX等,使用CreateWindow可以直接调用。

对话框分为两种:

  • 模态对话框(阻塞父窗口)
  • 非模态对话框(不阻塞父窗口)

模态对话框创建过程

  1. 设计对话框资源模板
  2. 实现对话框过程函数
  3. 创建对话框

1.设计对话框资源模板

资源视图->右键菜单->添加资源->Dialog

2.实现对话框过程函数

DialogProc对话框过程函数,如果处理了消息返回True,如果没有处理返回False 会自动处理。

//模态对话框过程函数
INT_PTR CALLBACK DialogProc(
    HWND hwndDlg,  // handle to dialog box
    UINT uMsg,     // message  
    WPARAM wParam, // first message parameter
    LPARAM lParam  // second message parameter
)
{
    switch (uMsg)
    {
    case WM_CLOSE:
    {
        //向消息队列中投递一个WM_QUIT消息用来结束消息循环。
        EndDialog(hwndDlg, NULL);//这里需要使用EndDialog,否则会阻塞父窗口
        return TRUE;
    }
    default:
        break;
    }
    return FALSE;
}
//创建对话框
DialogBox(
    GetModuleHandle(NULL), //实例句柄
    MAKEINTRESOURCE(IDD_DIALOG1),//资源ID
    hwnd,//句柄
    (DLGPROC)DialogProc//模态对话框过程函数
)

模态对话框阻塞父窗口的原因

  1. 内部自建消息循环
  2. 内部调用EnableWindow(禁用鼠标和键盘输入到指定的窗口或控件)

WM_INITDIA该消息用于初始化对话框。

LRESULT CALLBACK WindowProc(
  HWND hwnd,       // handle to window
  UINT uMsg,       // WM_INITDIALOG
  WPARAM wParam,   // handle to control (HWND) 窗口句柄
  LPARAM lParam    // 调用对话框时,设置为NULL
);

测试在模态对话框初始化时开启EnableWindow

case WM_INITDIALOG:
{
    HWND hParent = GetParent(hwndDlg);//给予子窗口句柄返回父窗口
    EnableWindow(hParent, TRUE);//允许父窗口接收键盘和鼠标输入
    return TRUE;
}

开启后,在模态对话框运行时,父窗口仍然可以接收鼠标和键盘的消息。

非模态对话框

非模态对话框弹出时不会阻塞父窗口

  • CreateDialog 创建非模态对话框

  • ShowWindow 显示非模态对话框

  • DestroyWindow销毁对话框时调用

非模态对话框和父窗口共用用一个消息循环 。

控件

视图->工具箱->对话框编辑器

MDSN查询常用控件消息

msdn打开以下路径,查看常用控件消息。

目录->MSDN Library -> Platform SDK Documentation -> User Interface Services ->WindowsUser Interface -> Controls

按钮

按钮所有消息

Buttons->Button Reference->Button Message

前缀以N结尾的消息,当按钮状态发生改变时进行告知。

前缀以M结尾的消息,对按钮做操作。

处理鼠标点击

BN_CLICKED按钮按下。

LRESULT CALLBACK WindowProc(
  HWND hwnd,       // handle to window
  UINT uMsg,       // WM_COMMAND
  WPARAM wParam,   // identifier of button, BN_CLICKED//按钮的Id
  LPARAM lParam    // handle to button (HWND)//为按钮的句柄
);

wParam高位是消息的ID,底位是控件的ID。

case WM_COMMAND:
{
    WORD wMessage = HIWORD(wParam);//控件消息
    WORD wControlId = LOWORD(wParam);//控件的Id
    switch (wMessage)
    {
    case BN_CLICKED:
    {
        switch (wControlId)
        {
        case IDC_BUTTON_TEST:
        {
            MessageBox(hwndDlg, "按钮点击", NULL, MB_OK);
            break;
        }
        case IDC_BUTTON_TEST2:
        {
            MessageBox(hwndDlg, "按钮点击2", NULL, MB_OK);
            break;
        }
        }
    }
    }
    return 0;
}

模拟鼠标点击

BM_CLICK 模拟鼠标点击

GetDlgItem拿到对话框中控件的窗口句柄。

case IDC_BUTTON_SEND:
{
    //获取按钮的窗口句柄
    HWND hBtn2 = GetDlgItem(hwndDlg,IDC_BUTTON_TEST2);
    //向按钮发送消息,模拟鼠标点击
    SendMessage(hBtn2, BM_CLICK, 0, 0);
    break;
}

文本编辑框

  • Password 密码输入框
  • Read Only 只读
  • Number 只输入数字

CTRL + T预览窗口

获取编辑框内容

使用GetLine按行获取文本内容。

case BTN_GETTEXT:
{
    HWND hEdit = GetDlgItem(hwndDlg, IDC_EDIT_TEST);
    char szBuff[MAXBYTE] = { 0 };
    //缓冲区第一个字的内容,为缓冲区的大小
    *(WORD *)szBuff = sizeof(szBuff);
    SendMessage(hEdit, EM_GETLINE, 0 , (LPARAM)szBuff);
    MessageBox(hwndDlg, szBuff, "编辑框内容", MB_OK);
    break;
}

使用WM_GETTEXT获取本文内容(可以用来获取控件标题)

case BTN_GETTEXT:
{
    HWND hEdit = GetDlgItem(hwndDlg, IDC_EDIT_TEST);
    char szBuff[MAXBYTE] = { 0 };
    SendMessage(hEdit, WM_GETTEXT, sizeof(szBuff), (LPARAM)szBuff);
    MessageBox(hwndDlg, szBuff, "编辑框内容", MB_OK);
    break;  
}

使用GetWindowText获取文本编辑框内容

 case BTN_GETTEXT:
 {
     HWND hEdit = GetDlgItem(hwndDlg, IDC_EDIT_TEST);
     char szBuff[MAXBYTE] = { 0 };
     GetWindowText(hEdit, szBuff, sizeof(szBuff));
     MessageBox(hwndDlg, szBuff, "编辑框内容", MB_OK);
     break;
 }

使用GetDlgItemText获取文本编辑框内容

case BTN_GETTEXT:
{
    char szBuff[MAXBYTE] = { 0 };
    GetDlgItemText(hwndDlg, IDC_EDIT_TEST, szBuff, sizeof(szBuff));
    MessageBox(hwndDlg, szBuff, "编辑框内容", MB_OK);
    break;
}

设置编辑框文本内容,将上面GET改为SET即可

列表框

增加内容

关闭列表框自动排序功能。

LB_ADDSTRING

case IDC_BUTTON_ADD:
{
    char szBuff[MAXBYTE] = { 0 };
    GetDlgItemText(hwndDlg, IDC_EDIT1, szBuff, sizeof(szBuff));
    HWND hLstb = GetDlgItem(hwndDlg, IDC_LIST_TEXT);
    SendMessage(hLstb, LB_ADDSTRING, 0, (LPARAM)szBuff);
    break;
}

删除功能

LB_GETCURSEL 获取当前选中项的索引值。

LB_DELETESTRING 删除列表框中的内容

case IDC_BUTTON_DEL:
{
    HWND hLstb = GetDlgItem(hwndDlg, IDC_LIST_TEXT);
    //获取被选中的索引值
    int nIndex = SendMessage(hLstb, LB_GETCURSEL, 0, 0);

    //删除被选中的项
    SendMessage(hLstb, LB_DELETESTRING, nIndex, 0);
    break;
}

获取内容

LB_GETTEXTLEN获取长度

case IDC_BUTTON_GET:
{
    HWND hLstb = GetDlgItem(hwndDlg, IDC_LIST_TEXT);
    //获取被选中的索引值
    int nIndex = SendMessage(hLstb, LB_GETCURSEL, 0, 0);
    //获取字符串
    char szBuff[MAXBYTE] = { 0 };
    SendMessage(hLstb, LB_GETTEXT, nIndex, (LPARAM)szBuff);
    MessageBox(NULL, szBuff, NULL, MB_OK);
    break;
}


致谢
科锐逆向

by:37期学员
感谢分享
使用道具 举报 回复
已阅
使用道具 举报 回复
J0o1ey 超级版主 培训/业务/联系Q547006660 秦 春秋文阁 春秋游侠 核心白帽 i春秋签约作者 幽默灌水王 积极活跃奖 白帽高手
地板
发表于 6 天前
感谢师傅分享,日后恶补开发
有培训需求或是技术交流需求的朋友可以联系我~QQ547006660|交流群820783253|团队首页www.gcowsec.com|
使用道具 举报 回复
感谢分享,学习了~
使用道具 举报 回复
感谢师傅分享
使用道具 举报 回复
感谢师傅分享
论如何学习,我们来聊一聊经验呀784278256
使用道具 举报 回复
发新帖
您需要登录后才可以回帖 登录 | 立即注册