首页 > 技术文章 > win32 API编程之窗口操作

mango1997 2021-04-07 14:47 原文

一、控件或子窗口操作

二、控件或窗口操作

三、窗口子类化

四、窗口超类化

 

 

一、控件或子窗口操作

 

①GetDlgItem函数

②GetDlgItemText函数

③SetDlgItemText函数

④SendDlgItemMessage函数

 代码实例

#include<windows.h>
#include<CommCtrl.h>  
//使用Unicode版本必须加入manifest强制让应用程序加载common Control 6.0
//#pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"")  
//#pragma comment(lib,"Comctl32.lib")


//自定义的窗口过程
LRESULT  CALLBACK    MyWindowProc(HWND hWnd, UINT Msg,
    WPARAM wParam, LPARAM lParam)
{
    switch (Msg)
    {
    case WM_DESTROY:
        PostQuitMessage(0);//可以使GetMessage返回0    
        return 0;  

     case WM_CREATE:
      {  

          HWND hBtn = CreateWindow(WC_BUTTON,
              L"按钮控件",
              WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON,
              30, 30,
              100, 30,
              hWnd,
              (HMENU)111,
              ((LPCREATESTRUCT)lParam)->hInstance,
              NULL); 

          HWND hEdit = CreateWindow(WC_EDIT,
              L"123",
              WS_CHILD | WS_VISIBLE | WS_BORDER,
              30, 100,
              200, 30,
              hWnd,
              (HMENU)222,
              ((LPCREATESTRUCT)lParam)->hInstance,
              NULL);

          //通过控件ID获取句柄
          HWND   h1= GetDlgItem(hWnd, 111);
          bool  b = (h1 == hBtn);
          HWND   h2 = GetDlgItem(hWnd, 222);
          bool  b2 = (h2 == hEdit);

          //获取控件的文本或标题
          TCHAR  buf[64] = {0};
          GetDlgItemText(hWnd, 111, buf, 64);
          GetDlgItemText(hWnd, 222, buf, 64);
          OutputDebugString(buf);

          //获取控件文本并转化为整数
          BOOL  bSuccess = FALSE;
          int  v1=GetDlgItemInt(hWnd, 111, &bSuccess, true);
          bSuccess = FALSE;
          int  v2 = GetDlgItemInt(hWnd, 222, &bSuccess, true);
           
          //根据控件句柄获取ID
          UINT  id1= GetDlgCtrlID(hBtn);
          UINT  id2 = GetDlgCtrlID(hEdit);
          UINT  id3 = GetDlgCtrlID(hWnd); //顶层窗口没有ID,返回0
          id3 = id3;

          //根据ID设置控件的文本或者标题
          SetDlgItemText(hWnd, 111, L"你好啊!");
          SetDlgItemText(hWnd, 222, L"456");

          //根据ID将整数设置控件的文本或者标题
          SetDlgItemInt(hWnd, 111, 666, true);
          SetDlgItemInt(hWnd, 222, -888, true);

          //根据控件ID向控件发送指定的消息
          SendDlgItemMessage(hWnd, 222, WM_SETTEXT, 0,(LPARAM) L"这是消息!");
           

       }break;
    }

    return DefWindowProc(hWnd, Msg, wParam, lParam);
}


int  WINAPI   WinMain(HINSTANCE  hInstance, HINSTANCE  hPrevInstance,
    LPSTR lpCmdLine, int  nShowCmd)
{

    //1.注册窗口类
    WNDCLASS  wnd;
    wnd.cbClsExtra = 0;
    wnd.cbWndExtra = 0;
    wnd.hbrBackground = (HBRUSH)(GetStockObject(GRAY_BRUSH));//背景色
    wnd.hCursor = LoadCursor(NULL, IDC_ARROW);//光标
    wnd.hIcon = LoadIcon(NULL, IDI_APPLICATION);//图标
                                                //wnd.lpfnWndProc = DefWindowProc;//默认窗口过程函数,用于处理消息
    wnd.lpfnWndProc = MyWindowProc;//自定义的窗口过程函数
    wnd.lpszClassName = L"MrHuang";//窗口类名
    wnd.lpszMenuName = NULL;//菜单资源名称
    wnd.style = CS_HREDRAW | CS_DBLCLKS;//窗口类、样式
    wnd.hInstance = hInstance;//实例句柄
    RegisterClass(&wnd);

    //创建窗口(返回之前发送WM_CREATE)
    HWND    hWnd = CreateWindow(L"MrHuang", L"第一个窗口程序",
        WS_OVERLAPPEDWINDOW, 100, 100, 400, 400, NULL, NULL, hInstance, NULL);

    //显示窗口
    ShowWindow(hWnd, nShowCmd);
    //更新窗口(发送WM_PAINT)
    UpdateWindow(hWnd); 


    //消息循环(收到WM_QUIT消息退出)
    MSG  msg;
    while (GetMessage(&msg, NULL, 0, 0))
    {
        TranslateMessage(&msg);//翻译消息
        DispatchMessage(&msg);//分发消息到窗口过程
    }
}

 

二、控件或窗口操作

①EnableWindow函数

②FindWindow函数

③SetWindowText函数

④GetWindowText函数

⑤GetWindowRect函数

⑥GetClientRect函数

⑦GetActiveWindow函数

代码实例

#include<windows.h>
#include<CommCtrl.h>  
//使用Unicode版本必须加入manifest强制让应用程序加载common Control 6.0
//#pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"")  
//#pragma comment(lib,"Comctl32.lib")


//自定义的窗口过程
LRESULT  CALLBACK    MyWindowProc(HWND hWnd, UINT Msg,
    WPARAM wParam, LPARAM lParam)
{
    switch (Msg)
    {
    case WM_DESTROY:
        PostQuitMessage(0);//可以使GetMessage返回0    
        return 0;
         
    case  WM_LBUTTONDOWN:
        {
            //获取当前活动的窗口
            HWND  hActive = GetActiveWindow();
            TCHAR buf[64] = { 0 };
            GetWindowText(hActive, buf, 64);
            MessageBox(NULL, buf, L"提示", MB_OK);

        }break;


    case WM_CREATE:
    {

        HWND hEdit1 = CreateWindow(WC_EDIT,
            L"编辑控件",
            WS_CHILD | WS_VISIBLE ,
            30, 30,
            100, 30,
            hWnd,
            (HMENU)111,
            ((LPCREATESTRUCT)lParam)->hInstance,
            NULL);

        HWND hEdit2 = CreateWindow(WC_EDIT,
            L"123",
            WS_CHILD | WS_VISIBLE | WS_BORDER,
            30, 100,
            200, 30,
            hWnd,
            (HMENU)222,
            ((LPCREATESTRUCT)lParam)->hInstance,
            NULL);

        //根据窗口句柄禁用或启用窗口
        EnableWindow(hEdit1,false);
        EnableWindow(hEdit1, true);
        //EnableWindow(hWnd, false);//禁用父窗口


        //根据窗口类名、窗口标题查找顶层窗口(父窗口)
        HWND   h1 = FindWindow(L"MrHuang", NULL);
        bool  b1 = (h1 == hWnd);
        HWND   h2 = FindWindow(NULL, L"第一个窗口程序");
        bool  b2 = (h2 == hWnd);
        HWND   h3 = FindWindow(L"Mr", L"第一个窗口程序");
        bool  b3 = (h3 == hWnd);
        HWND   h4 = FindWindow(WC_EDIT,  NULL);//不能用于子窗口与控件
        bool  b4 = (h4 == hEdit2);
     
        HWND   hTxt= FindWindow(NULL, L"新建文本文档.txt - 记事本");//查找记事本
        SendMessage(hTxt, WM_SETTEXT, 0,(LPARAM)L"篡改你的标题");

        //根据窗口句柄设置窗口标题
        //SetWindowText(hWnd, L"改掉标题");
        //SetWindowText(hEdit1, L"改掉标题");

        //根据窗口句柄获取窗口标题
        TCHAR buf[64] = {0};
        GetWindowText(hEdit2, buf, 64);
        OutputDebugString(buf);

        //获取窗口的矩形区域
        RECT  r;
        GetWindowRect(hWnd, &r);
         
        //获取窗口的客户区域
        RECT  r2;
        GetClientRect(hWnd, &r2);

      //设置控件具有焦点
        SetFocus(hEdit1);

        //根据窗口句柄移动窗口
        //MoveWindow(hWnd, 0, 0, 600, 600, true);//移动父窗口
        //MoveWindow(hEdit2, 300, 300, 100, 100, true);//移动控件

        //获取当前活动的窗口
        HWND  hActive = GetActiveWindow();
        bool  b8 = (hActive == hWnd);
         

    }break;
    }

    return DefWindowProc(hWnd, Msg, wParam, lParam);
}


int  WINAPI   WinMain(HINSTANCE  hInstance, HINSTANCE  hPrevInstance,
    LPSTR lpCmdLine, int  nShowCmd)
{

    //1.注册窗口类
    WNDCLASS  wnd;
    wnd.cbClsExtra = 0;
    wnd.cbWndExtra = 0;
    wnd.hbrBackground = (HBRUSH)(GetStockObject(GRAY_BRUSH));//背景色
    wnd.hCursor = LoadCursor(NULL, IDC_ARROW);//光标
    wnd.hIcon = LoadIcon(NULL, IDI_APPLICATION);//图标
                                                //wnd.lpfnWndProc = DefWindowProc;//默认窗口过程函数,用于处理消息
    wnd.lpfnWndProc = MyWindowProc;//自定义的窗口过程函数
    wnd.lpszClassName = L"MrHuang";//窗口类名
    wnd.lpszMenuName = NULL;//菜单资源名称
    wnd.style = CS_HREDRAW | CS_DBLCLKS;//窗口类、样式
    wnd.hInstance = hInstance;//实例句柄
    RegisterClass(&wnd);

    //创建窗口(返回之前发送WM_CREATE)
    HWND    hWnd = CreateWindow(L"MrHuang", L"第一个窗口程序",
        WS_OVERLAPPEDWINDOW, 100, 100, 400, 400, NULL, NULL, hInstance, NULL);

    //显示窗口
    ShowWindow(hWnd, nShowCmd);
    //更新窗口(发送WM_PAINT)
    UpdateWindow(hWnd);


    //创建窗口(返回之前发送WM_CREATE)
    HWND    hWnd2 = CreateWindow(L"MrHuang", L"第二个窗口程序",
        WS_OVERLAPPEDWINDOW, 500, 100, 400, 400, NULL, NULL, hInstance, NULL);

    //显示窗口
    ShowWindow(hWnd2, nShowCmd);
    //更新窗口(发送WM_PAINT)
    UpdateWindow(hWnd2);



    //消息循环(收到WM_QUIT消息退出)
    MSG  msg;
    while (GetMessage(&msg, NULL, 0, 0))
    {
        TranslateMessage(&msg);//翻译消息
        DispatchMessage(&msg);//分发消息到窗口过程
    }
}

三、窗口子类化

1)什么是窗口子类化

2)窗口子类化的步骤

3)GetWindowLong函数

4)SetWindowLong函数

5)nIndex的值

6)CallWindowProc函数

7)如何截获并处理感兴趣的消息

8)代码实例

#include<windows.h>


WNDPROC  oldProc = NULL;

//自定义的编辑框窗口处理函数
LRESULT  CALLBACK    MyEditWindowProc(HWND hWnd, UINT Msg,
    WPARAM wParam, LPARAM lParam)
{
    switch (Msg)
    {
        //处理了感兴趣的消息
      case WM_LBUTTONDOWN:
        //MessageBox(hWnd, L"我们截获了编辑框的消息", L"提示", MB_OK); 
          SetWindowText(hWnd, L"我们截获了编辑框的消息");
     //  return 0; //表示我们自己处理了

      case  WM_RBUTTONDOWN:
     
          break;
    }

    //其它的消息交给它原来的处理过程函数去处理,保证控件的正确性
    return  CallWindowProc(oldProc,hWnd, Msg,wParam,lParam);
}



 
LRESULT  CALLBACK    MyWindowProc(HWND hWnd, UINT Msg,
    WPARAM wParam, LPARAM lParam)
{
    switch (Msg)
    {
    case WM_DESTROY:
        PostQuitMessage(0);//可以使GetMessage返回0    
        return 0;

    case WM_CREATE:
    {

        //创建系统预定义的控件(源代码不可修改)
        HWND hEdit = CreateWindow(L"EDIT",
            L"111",
            WS_CHILD | WS_VISIBLE | WS_BORDER,
            30, 30,
            200, 30,
            hWnd,
            (HMENU)111,
            ((LPCREATESTRUCT)lParam)->hInstance,
            NULL);
         
        //将控件的窗口过程处理函数改为自定义的,从而捕获控件消息
        oldProc=(WNDPROC)SetWindowLong(hEdit, GWL_WNDPROC, (LONG)MyEditWindowProc);

    }break;
    }

    return DefWindowProc(hWnd, Msg, wParam, lParam);
}


int  WINAPI   WinMain(HINSTANCE  hInstance, HINSTANCE  hPrevInstance,
    LPSTR lpCmdLine, int  nShowCmd)
{

    //1.注册窗口类
    WNDCLASS  wnd;
    wnd.cbClsExtra = 0;
    wnd.cbWndExtra = 0;
    wnd.hbrBackground = (HBRUSH)(GetStockObject(GRAY_BRUSH));//背景色
    wnd.hCursor = LoadCursor(NULL, IDC_ARROW);//光标
    wnd.hIcon = LoadIcon(NULL, IDI_APPLICATION);//图标
                                                //wnd.lpfnWndProc = DefWindowProc;//默认窗口过程函数,用于处理消息
    wnd.lpfnWndProc = MyWindowProc;//自定义的窗口过程函数
    wnd.lpszClassName = L"MrHuang";//窗口类名
    wnd.lpszMenuName = NULL;//菜单资源名称
    wnd.style = CS_HREDRAW | CS_DBLCLKS;//窗口类、样式
    wnd.hInstance = hInstance;//实例句柄
    RegisterClass(&wnd);

    //创建窗口(返回之前发送WM_CREATE)
    HWND    hWnd = CreateWindow(L"MrHuang", L"第一个窗口程序",
        WS_OVERLAPPEDWINDOW, 100, 100, 400, 400, NULL, NULL, hInstance, NULL);

    //显示窗口
    ShowWindow(hWnd, nShowCmd);
    //更新窗口(发送WM_PAINT)
    UpdateWindow(hWnd);

    //消息循环(收到WM_QUIT消息退出)
    MSG  msg;
    while (GetMessage(&msg, NULL, 0, 0))
    {
        TranslateMessage(&msg);//翻译消息
        DispatchMessage(&msg);//分发消息到窗口过程
    }
}

四、窗口超类化

1)什么是窗口超类化

2)超类化步骤

3)GetClassInfo函数

4)代码实例

#include<windows.h>
#include<CommCtrl.h> 


WNDPROC  oldProc = NULL;

LRESULT CALLBACK  MyEditWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
    switch (msg)
    {
        // 点击鼠标左键,显示一个消息框。 
    case WM_LBUTTONDOWN:
    {
        //MessageBox(0, L"我拦截了左键的行为", L"提示", MB_OK);
        SetWindowText(hWnd, L"我拦截了编辑框左键的行为");
        //return 0; //自己处理消息,就必须返回0。
    } break;

    }
    return    CallWindowProc(oldProc, hWnd, msg, wParam, lParam);
}



//自定义的窗口过程
LRESULT  CALLBACK    MyWindowProc(HWND hWnd, UINT Msg,
    WPARAM wParam, LPARAM lParam)
{
    switch (Msg)
    {
    case WM_DESTROY:
        PostQuitMessage(0);//可以使GetMessage返回0    
        return 0;

    case WM_CREATE:
    { 

        //先获取系统控件的WNDCLASS信息
        WNDCLASS  wc;
        GetClassInfo(NULL, WC_EDIT, &wc); 
        oldProc = wc.lpfnWndProc;//保存系统的窗口处理函数
        wc.lpfnWndProc = MyEditWndProc;//改为自定义的窗口处理函数
        bool  ret=RegisterClass(&wc); //重新注册窗口类,实现全局的生效

        //备注:也可以改为自己的窗口类名,后续创建的时候用自己的窗口类名就可以创建编辑框

        //系统预定义的控件,无法修改
        HWND hEdit = CreateWindow(WC_EDIT,
            L"111",
            WS_CHILD | WS_VISIBLE | WS_BORDER,
            30, 30,
            200, 30,
            hWnd,
            (HMENU)111,
            ((LPCREATESTRUCT)lParam)->hInstance,
            NULL); 


        //系统预定义的控件,无法修改
        HWND hEdit2 = CreateWindow(WC_EDIT,
            L"222",
            WS_CHILD | WS_VISIBLE | WS_BORDER,
            30, 100,
            200, 30,
            hWnd,
            (HMENU)111,
            ((LPCREATESTRUCT)lParam)->hInstance,
            NULL);
         

    }break;
    }

    return DefWindowProc(hWnd, Msg, wParam, lParam);
}


int  WINAPI   WinMain(HINSTANCE  hInstance, HINSTANCE  hPrevInstance,
    LPSTR lpCmdLine, int  nShowCmd)
{

    //1.注册窗口类
    WNDCLASS  wnd;
    wnd.cbClsExtra = 0;
    wnd.cbWndExtra = 0;
    wnd.hbrBackground = (HBRUSH)(GetStockObject(GRAY_BRUSH));//背景色
    wnd.hCursor = LoadCursor(NULL, IDC_ARROW);//光标
    wnd.hIcon = LoadIcon(NULL, IDI_APPLICATION);//图标
                                                //wnd.lpfnWndProc = DefWindowProc;//默认窗口过程函数,用于处理消息
    wnd.lpfnWndProc = MyWindowProc;//自定义的窗口过程函数
    wnd.lpszClassName = L"MrHuang";//窗口类名
    wnd.lpszMenuName = NULL;//菜单资源名称
    wnd.style = CS_HREDRAW | CS_DBLCLKS;//窗口类、样式
    wnd.hInstance = hInstance;//实例句柄
    RegisterClass(&wnd);

    //创建窗口(返回之前发送WM_CREATE)
    HWND    hWnd = CreateWindow(L"MrHuang", L"第一个窗口程序",
        WS_OVERLAPPEDWINDOW, 100, 100, 400, 400, NULL, NULL, hInstance, NULL);

    //显示窗口
    ShowWindow(hWnd, nShowCmd);
    //更新窗口(发送WM_PAINT)
    UpdateWindow(hWnd);

    //消息循环(收到WM_QUIT消息退出)
    MSG  msg;
    while (GetMessage(&msg, NULL, 0, 0))
    {
        TranslateMessage(&msg);//翻译消息
        DispatchMessage(&msg);//分发消息到窗口过程
    }
}

 

推荐阅读