`
lobin
  • 浏览: 383434 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

Windows Win32编程 - 窗口

 
阅读更多

窗口

通常,我们理解的窗口是如下这样的窗口。我们经常所看到的这种窗口只是一个标准窗口。除了这种标准窗口,还有好几种或者说好多其他类型的窗口。

标准窗口

Pop-Up窗口

 

对话框

对话框也是一种窗口。

 

桌面窗口

也就是我们常说的桌面,Desktop或者DesktopWindow,这也是一种窗口。

 

 

桌面窗口

 

 

窗口类

Windows下的窗口有个窗口类。Windows下的窗口类包括系统类,应用程序全局类以及应用程序本地类三类。系统类是Windows提供的可以直接使用,不需要注册的窗口类。应用程序全局类以及应用程序本地类是需要调用RegisterClass函数进行注册。

 

要实现一个窗口,需要注册一个窗口类。刚开始编写Windows的窗口界面时,如果不了解Windows下的窗口注册,想要实现一个通常意义下的窗口,上面的标准窗口,这个工作还有点麻烦,因为需要自己注册一个窗口类,Windows的系统窗口类并没有这样的窗口类,到是有个对话框窗口,窗口类为#32770,可以直接使用,不过这毕竟还是跟普通的标准窗口还是有些不同。

写道
https://docs.microsoft.com/en-us/windows/win32/winmsg/about-window-classes?redirectedfrom=MSDN

注册窗口类

 

创建窗口

调用CreateWindow或者CreateWindowEx函数创建窗口。

 

CreateWindow

HWND CreateWindow( 
  LPCTSTR lpClassName, 
  LPCTSTR lpWindowName, 
  DWORD dwStyle, 
  int x, 
  int y, 
  int nWidth, 
  int nHeight, 
  HWND hWndParent, 
  HMENU hMenu, 
  HANDLE hInstance, 
  PVOID lpParam 
);

CreateWindowEx

HWND CreateWindowEx(
  DWORD dwExStyle, 
  LPCTSTR lpClassName, 
  LPCTSTR lpWindowName, 
  DWORD dwStyle, 
  int x, a
  int y, 
  int nWidth, 
  int nHeight, 
  HWND hWndParent, 
  HMENU hMenu, 
  HINSTANCE hInstance, 
  LPVOID lpParam 
);

这两个函数都返回一个窗口句柄。

 

窗口句柄

句柄在Win32 API中是一个很重要的概念。后续所有和窗口相关的操作都需要这个窗口句柄。

 

除了窗口句柄(HWND),还有HMODULE、HINSTANCE等。

 

窗口事件处理

 

窗口处理函数

函数原型

LRESULT CALLBACK WindowProc(
  HWND hwnd, 
  UINT uMsg, 
  WPARAM wParam, 
  LPARAM lParam 
);

 

父窗口

子窗口

 

窗口拥有者

 

窗口被拥有者

 

标准窗口

#include <stdio.h>
#include <windows.h>

#include "window.h"

LRESULT CALLBACK WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
  PAINTSTRUCT ps;
  HDC hDC;

  switch (uMsg) 
  {
    case WM_CREATE:
    {
      printf("[WM_CREATE] \n");
      break;
    }
    case WM_COMMAND:
      printf("[WM_COMMAND] \n");
      break;
    case WM_PAINT:
    {
      printf("[WM_PAINT] \n");
      hDC = BeginPaint(hWnd, &ps);

      EndPaint(hWnd, &ps);
      break;
    }
    case WM_DESTROY:
      printf("[WM_DESTROY] \n");
      PostQuitMessage(0);
      printf("Goodbye!.\n");
      break;
    default:
      return DefWindowProc(hWnd, uMsg, wParam, lParam);
  }
  return 0;
}

int main(int argc, char *argv[])
{
  HMODULE hModule;

  LPCTSTR hWndCls;
  HWND hWnd;

  int nCmdShow  = SW_SHOW;

  MSG msg;

  hModule = GetModuleHandle(NULL);
  if (hModule == NULL)
  {
    DWORD error = GetLastError();
    printf("GetModuleHandle err=%d\n", error);
    return -1;
  }

  hWndCls = register_window_class(hModule, WindowProc);
  
  hWnd = CreateWindow(hWndCls, TEXT("主窗口"), 0 /* styles */, 0, 0, 500, 500, NULL, NULL, hModule, NULL);
  if (! hWnd)
  {
    DWORD error = GetLastError();
    printf("CreateWindow err=%d\n", error);
    return -1;
  }

  ShowWindow(hWnd, nCmdShow);

  UpdateWindow(hWnd);

  while (GetMessage(&msg, NULL, 0, 0)) 
  {
    TranslateMessage(&msg);
    DispatchMessage(&msg);
  }

  printf("exit.\n");
  return 0;
}

  

如果需要实现一个无标题栏、无边框的窗口,使用Pop-Up窗口是最简单的实现方式。当然,通过上面的标准窗口,也可以实现。

 

透明窗口

 

Pop-Up窗口 

无标题栏

#include <stdio.h>
#include <windows.h>

#include "window.h"

LRESULT CALLBACK WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
  PAINTSTRUCT ps;
  HDC hDC;

  switch (uMsg) 
  {
    case WM_CREATE:
    {
      printf("[WM_CREATE] \n");
      break;
    }
    case WM_COMMAND:
      printf("[WM_COMMAND] \n");
      break;
    case WM_PAINT:
    {
      printf("[WM_PAINT] \n");
      hDC = BeginPaint(hWnd, &ps);

      EndPaint(hWnd, &ps);
      break;
    }
    case WM_DESTROY:
      printf("[WM_DESTROY] \n");
      PostQuitMessage(0);
      printf("Goodbye!.\n");
      break;
    default:
      return DefWindowProc(hWnd, uMsg, wParam, lParam);
  }
  return 0;
}

int main(int argc, char *argv[])
{
  HMODULE hModule;

  LPCTSTR hWndCls;
  HWND hWnd;
  LONG_PTR style;

  int nCmdShow  = SW_SHOW;

  MSG msg;

  hModule = GetModuleHandle(NULL);
  if (hModule == NULL)
  {
    DWORD error = GetLastError();
    printf("GetModuleHandle err=%d\n", error);
    return -1;
  }

  hWndCls = register_window_class(hModule, WindowProc);
  
  hWnd = CreateWindow(hWndCls, TEXT("主窗口"), WS_VISIBLE | WS_POPUP | WS_THICKFRAME /* styles */, 0, 0, 500, 500, NULL, NULL, hModule, NULL);
  if (! hWnd)
  {
    DWORD error = GetLastError();
    printf("CreateWindow err=%d\n", error);
    return -1;
  }
  ShowWindow(hWnd, nCmdShow);

  UpdateWindow(hWnd);

  while (GetMessage(&msg, NULL, 0, 0)) 
  {
    TranslateMessage(&msg);
    DispatchMessage(&msg);
  }

  printf("exit.\n");
  return 0;
}

 无标题栏无边框

#include <stdio.h>
#include <windows.h>

#include "window.h"

LRESULT CALLBACK WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
  PAINTSTRUCT ps;
  HDC hDC;

  switch (uMsg) 
  {
    case WM_CREATE:
    {
      printf("[WM_CREATE] \n");
      break;
    }
    case WM_COMMAND:
      printf("[WM_COMMAND] \n");
      break;
    case WM_PAINT:
    {
      printf("[WM_PAINT] \n");
      hDC = BeginPaint(hWnd, &ps);

      EndPaint(hWnd, &ps);
      break;
    }
    case WM_DESTROY:
      printf("[WM_DESTROY] \n");
      PostQuitMessage(0);
      printf("Goodbye!.\n");
      break;
    default:
      return DefWindowProc(hWnd, uMsg, wParam, lParam);
  }
  return 0;
}

int main(int argc, char *argv[])
{
  HMODULE hModule;

  LPCTSTR hWndCls;
  HWND hWnd;
  LONG_PTR style;

  int nCmdShow  = SW_SHOW;

  MSG msg;

  hModule = GetModuleHandle(NULL);
  if (hModule == NULL)
  {
    DWORD error = GetLastError();
    printf("GetModuleHandle err=%d\n", error);
    return -1;
  }

  hWndCls = register_window_class(hModule, WindowProc);
  
  hWnd = CreateWindow(hWndCls, TEXT("主窗口"), WS_VISIBLE | WS_POPUP/* styles */, 0, 0, 500, 500, NULL, NULL, hModule, NULL);
  if (! hWnd)
  {
    DWORD error = GetLastError();
    printf("CreateWindow err=%d\n", error);
    return -1;
  }
  ShowWindow(hWnd, nCmdShow);

  UpdateWindow(hWnd);

  while (GetMessage(&msg, NULL, 0, 0)) 
  {
    TranslateMessage(&msg);
    DispatchMessage(&msg);
  }

  printf("exit.\n");
  return 0;
}

 

 

对话框

#include<windows.h>

#pragma comment(lib, "User32.lib")

int WINAPI wWinMain(HINSTANCE hInstance, 
                    HINSTANCE hPrevInstance, 
                    PWSTR pCmdLine, 
                    int nCmdShow)
{
  char *wc_name = "#32770";
  HWND hwnd;

  HACCEL hAccelTable;
  MSG msg;

  hwnd = CreateWindowEx(
    0,                                  // Optional window styles.
    TEXT(wc_name),                      // Window class
    TEXT("Dialog"),                     // Window text
    WS_OVERLAPPEDWINDOW,                // Window style

                                        // Size and position
    CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,

    NULL,                               // Parent window    
    NULL,                               // Menu
    hInstance,                          // Instance handle
    NULL                                // Additional application data
  );

  if (hwnd == NULL)
  {
    return GetLastError();
  }

  ShowWindow(hwnd, nCmdShow);
  UpdateWindow(hwnd);

  hAccelTable = LoadAccelerators(hInstance, TEXT(wc_name));
  while (GetMessage(&msg, NULL, 0, 0)) 
  {
    if (! TranslateAccelerator(msg.hwnd, hAccelTable, &msg)) 
    {
      TranslateMessage(&msg);
      DispatchMessage(&msg);
    }
  }

  return 0;
}

对话框窗口事件处理

#include<stdio.h>
#include<windows.h>

#pragma comment(lib, "User32.lib")

LRESULT CALLBACK WindowProc(
  HWND   hwnd,
  UINT   uMsg,
  WPARAM wParam,
  LPARAM lParam)
{
  switch(uMsg) 
  {
    case WM_COMMAND:
      if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL) 
      {
        EndDialog(hwnd, LOWORD(wParam));
        return TRUE;
      }
      break;
    default: 
      return DefDlgProc(hwnd, uMsg, wParam, lParam);
  }
  return 0;
}

int WINAPI wWinMain(HINSTANCE hInstance, 
                    HINSTANCE hPrevInstance, 
                    PWSTR pCmdLine, 
                    int nCmdShow)
{
  char *wc_name = "#32770";
  HWND hwnd;

  HACCEL hAccelTable;
  MSG msg;

  AllocConsole();
  freopen("conout$", "w", stdout);

  hwnd = CreateWindowEx(
    0,                                  // Optional window styles.
    TEXT(wc_name),                      // Window class
    TEXT("Dialog"),                     // Window text
    WS_OVERLAPPEDWINDOW,                // Window style

                                        // Size and position
    CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,

    NULL,                               // Parent window    
    NULL,                               // Menu
    hInstance,                          // Instance handle
    NULL                                // Additional application data
  );

  if (hwnd == NULL)
  {
    return GetLastError();
  }

  ShowWindow(hwnd, nCmdShow);
  UpdateWindow(hwnd);

  hAccelTable = LoadAccelerators(hInstance, TEXT(wc_name));
  while (GetMessage(&msg, hwnd, 0, 0)) 
  {
    if (! TranslateAccelerator(msg.hwnd, hAccelTable, &msg)) 
    {
      //TranslateMessage(&msg);
      //DispatchMessage(&msg);

      //DefWindowProc(msg.hwnd, msg.message, msg.wParam, msg.lParam);

      //DefDlgProc(msg.hwnd, msg.message, msg.wParam, msg.lParam);

      CallWindowProc(WindowProc, msg.hwnd, msg.message, msg.wParam, msg.lParam);
    }
  }

  return 0;
}

弹窗

#include <stdio.h>
#include <windows.h>

#include "window.h"

LRESULT CALLBACK WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
  PAINTSTRUCT ps;
  HDC hDC;

  switch (uMsg) 
  {
    case WM_CREATE:
    {
      printf("[WM_CREATE] \n");
      break;
    }
    /*
    case WM_ERASEBKGND: 
    {
      printf("[WM_ERASEBKGND] \n");
      break;
    }
    */
    case WM_COMMAND:
      printf("[WM_COMMAND] \n");
      break;
    case WM_PAINT:
    {
      printf("[WM_PAINT] \n");
      hDC = BeginPaint(hWnd, &ps);

      EndPaint(hWnd, &ps);
      break;
    }
    case WM_DESTROY:
      printf("[WM_DESTROY] \n");
      PostQuitMessage(0);
      printf("Goodbye!.\n");
      break;
    default:
      return DefWindowProc(hWnd, uMsg, wParam, lParam);
  }
  return 0;
}

int main(int argc, char *argv[])
{
  HMODULE hModule;

  HWND hDesktop;

  HWND hWnd;
  LPCTSTR hWndCls;
  LONG_PTR style;
  HBRUSH brush;

  int nCmdShow  = SW_SHOW;

  RECT rect;

  MSG msg;

  hModule = GetModuleHandle(NULL);
  if (hModule == NULL)
  {
    DWORD error = GetLastError();
    printf("GetModuleHandle err=%d\n", error);
    return -1;
  }

  hWndCls = register_window_class(hModule, CreateSolidBrush(RGB(0, 0, 255)), WindowProc);
  
  hWnd = CreateWindowEx(WS_EX_TOOLWINDOW, hWndCls, TEXT("弹窗"), 
      WS_VISIBLE | WS_POPUP/* styles */,
      0, 0, 280, 180, NULL, 0, hModule, NULL);
  if (! hWnd)
  {
    DWORD error = GetLastError();
    printf("CreateWindow err=%d\n", error);
    return -1;
  }

  hDesktop = GetDesktopWindow();
  if (hDesktop == NULL)
  {
    DWORD error = GetLastError();
    printf("GetDesktopWindow err=%d\n", error);
    return -1;
  }
  GetClientRect(hDesktop, &rect);
  SetWindowPos(hWnd, HWND_TOP, rect.right - 280, rect.bottom - 180, rect.right, rect.bottom, 0);


  ShowWindow(hWnd, nCmdShow);
  UpdateWindow(hWnd);

  //brush = CreateSolidBrush(RGB(0, 0, 0));
  //SetClassLong(hWnd, GCL_HBRBACKGROUND, (long) brush);

  while (GetMessage(&msg, NULL, 0, 0)) 
  {
    TranslateMessage(&msg);
    DispatchMessage(&msg);
  }

  printf("exit.\n");
  return 0;
}

 

 

 

 

分享到:
评论

相关推荐

    Win32编程设计一个功能及界面风格类似于Windows计算器的计算器程序

    说明: 希望大家不要直接用这个做课设,该程序以及报告仅供大家参考,希望对同学们的学习有...1.WIN32汇编程序编写。 2.用汇编实现简单的算法。 3.浮点数运算(浮点指令或者自己编程模拟)。 4.综合解决问题的能力。

    Windows窗口应用程序(Win32程序) 源代码

    https://blog.csdn.net/duke56/article/details/103411942 源代码 Win32应用程序,非MFC

    window32 API大全 win32编程

    作为Microsoft 32位平台的应用程序编程接口,Win32 API是从事Windows应用程序开发所必备的。本书首先对Win32 API函数做完整的概述;然后收录五大类函数:窗口管理、图形设备接口、系统服务、国际特性以及网络服务;...

    VC++ Win32编程基础实例

    Win32 Windows编程基础实例+源代码,内容涉及如下要点:  1 Windows编程基础  2 Windows文字的编码  3 窗口程序  4 窗口消息  5 菜单和加速键  6 绘图  7 对话框  8 基本控件  8个实例文件夹分别...

    Win32 API大全 收录五大类函数:窗口管理、图形设备接口、系统服务、国际特性以及网络服务;在附录部分,讲解如何在Visua

    作为Microsoft 32位平台的应用程序编程接口,Win32 API是从事Windows应用程序开发所必备的。本书首先对Win32 API函数做完整的概述;然后收录五大类函数:窗口管理、图形设备接口、系统服务、国际特性以及网络服务;...

    win32简单窗口编程.rar

    windows api 简单可视化窗口编程,其中包含EXE可执行程序和源注释代码,清晰简明。编译工具visual studio 2013专业版。一起学习qq:2306558119

    Windows界面编程第七篇 文件拖拽(文件拖放)

    《Windows界面编程第七篇 文件拖拽(文件拖放)》 http://blog.csdn.net/morewindows/article/details/8634451 配套程序。 使程序支持将文件拖入窗口的功能。Win32或MFC均能使用。

    Win32对话框编程

    里面含有6个工程,分别实现各种类型的对话框程序,模态对话框:包括基本对话框,含复杂控件的对话框,自定义按钮...非模态对话框包括:含有父窗口的模态对话框,利用脚本加载的自定义对话框,不含父窗口的对话框。

    用Win32API Shell_NotifyIcon进行托盘图标编程-源代码

    CODE: // 结构内存用0初使化 - 注意: 一些Windows函数要求这么做,不过我记不得哪些需要,哪些不需要了:) &lt;br&gt; NOTIFYICONDATA niData; ZeroMemory(&niData,sizeof(NOTIFYICONDATA)); &lt;br&gt;// 得到...

    Win32_SDK窗口程序代码

    Windows SDK编程 窗口示例程序

    win32api大全最全

    Win32 API作为 Microsoft 32位平台(包括:Windows 9x,Windows NT3.1/4.0/5.0,WindowsCE)的应用程序编程接口,它是构筑所有32位Windows平台的基石,所有在Windows平台上运行的应用程序都可以调用这些函数。...

    VC++ win32 API 游戏开发

    Windows API编程基础 典型的Windows程序结构 初学者必备资料!

    C++,win编程,获取当前选中win窗口输入数据

    C++,win编程,获取当前选中win窗口输入数据; 可做学习参考,完成初步获取,待后续更新 。

    新编Windows API参考大全_窗口管理_windowsapi_Win32API_图形设备接口_系统服务_

    作为Microsoft 32位平台的应用程序编程接口,Win32 API是从事Windows应用程序开发所必备的。本书首先对Win32 API函数做完整的概述;然后收录五大类函数:窗口管理、图形设备接口、系统服务、国际特性以及网络服务;...

    新编WIN32API大全

    作为Microsoft 32位平台的应用程序编程接口,Win32 API是从事Windows应用程序开发所必备的。本书首先对Win32 API函数做完整的概述;然后收录五大类函数:窗口管理、图形设备接口、系统服务、国际特性以及网络服务;...

    WIN-TC(C语言编程软件) v2.0.0

    WIN-TC免费版是一个turbo C2 WINDOWS平台开发工具,最大特点是支持中文界面,支持鼠标操作,程序段复制,WIN-TC免费版为初学c语言、对高等编程环境不熟悉的同志们非常有帮助。 WIN-TC免费版使用turbo C2为内核,提供...

    新编Win32API大全

    Win32 API作为 Microsoft 32位平台(包括:Windows 9x,Windows NT3.1/4.0/5.0,WindowsCE)的应用程序编程接口,它是构筑所有32位Windows平台的基石,所有在Windows平台上运行的应用程序都可以调用这些函数。...

    Win32 API参考手册(程序员必备API手册)

    作为Microsoft 32位平台的应用程序编程接口,Win32 API是从事Windows应用程序开发所必备的。本书首先对Win32 API函数做完整的概述;然后收录五大类函数:窗口管理、图形设备接口、系统服务、国际特性以及网络服务;...

    新编Win32API大全.chm

    作为Microsoft 32位平台的应用程序编程接口,Win32 API是从事Windows应用程序开发所必备的。本书首先对Win32 API函数做完整的概述;然后收录五大类函数:窗口管理、图形设备接口、系统服务、国际特性以及网络服务;...

Global site tag (gtag.js) - Google Analytics