对于不习惯用MFC的程序员来说,写界面应该是一个头疼的事情了。调用duilib等开源界面库的不讨论,本文主要说说Windows的原生界面功能开发,作为一篇总结,帮助新手入门。
1、窗口
主要通过新建资源窗口实现布局,调用就通过 DialogBox 和 CreateDialog 实现界面的显示。其中 DialogBox 为模态窗口, CreateDialog 为非模态窗口,简要说说区别:
模态窗口:在没有父窗口的时候,调用 DialogBox 实现显示窗口。系统在 DialogBox 这儿卡住,直到窗口关闭后继续以下的代码。
非模态窗口:调用 CreateDialog 之后,代码继续往下执行。如果没有父窗口,则执行 GetMessage TranslateMessage DispatchMessage 这几个代码,如果存在父窗口,则只需要进入父窗口的消息循环,子窗口也可以进行消息循环响应。
2、控件
Windows 下面的控件种类繁多,在此我简要介绍几种的使用
2.1、托盘图标
// // 文件:notifyicon.h // 类:hNotifyIcon // 主要功能:实现系统托盘图标设置 // #pragma once #include <Shellapi.h> class hNotifyIcon { NOTIFYICONDATA h_nid; public: hNotifyIcon (HWND hWnd, HICON hIcon, LPCTSTR lpTitle, LPCTSTR lpTips = NULL, int iTimeOut = 5); ~hNotifyIcon (); BOOL Show (); BOOL Hide (); BOOL Message (LPCTSTR lpMsg, UINT niif_InfoWarningError); BOOL IsShow (); };
// // 文件:notifyicon.cpp // 类:hNotifyIcon // 主要功能:实现系统托盘图标设置 // #include "notifyicon.h" #pragma comment(lib, "Shell32.lib") hNotifyIcon::hNotifyIcon (HWND hWnd, HICON hIcon, LPCTSTR lpTitle, LPCTSTR lpTips, int iTimeOut) { this->h_nid.cbSize = sizeof(NOTIFYICONDATA); this->h_nid.hWnd = hWnd; this->h_nid.uID = GetTickCount ()&0xFFFF; this->h_nid.dwState = this->h_nid.dwStateMask = 0; this->h_nid.uCallbackMessage = WM_USER+1; this->h_nid.hBalloonIcon = this->h_nid.hIcon = hIcon; if (lpTips) lstrcpy ((LPTSTR)this->h_nid.szTip, lpTips); else lstrcpy ((LPTSTR)this->h_nid.szTip, lpTitle); lstrcpy ((LPTSTR)this->h_nid.szInfoTitle, lpTitle); this->h_nid.uTimeout = iTimeOut; } hNotifyIcon::~hNotifyIcon () { if (this->IsShow ()) this->Hide (); } BOOL hNotifyIcon::Show () { this->h_nid.uFlags = NIF_ICON|NIF_INFO|NIF_MESSAGE; BOOL bRet = (BOOL) Shell_NotifyIcon (NIM_ADD, &this->h_nid); this->h_nid.uFlags = NIF_INFO; this->h_nid.dwInfoFlags = NIIF_INFO; return bRet; } BOOL hNotifyIcon::Hide () { this->h_nid.uFlags = NULL; return (BOOL) Shell_NotifyIcon (NIM_DELETE, &this->h_nid); } BOOL hNotifyIcon::Message (LPCTSTR lpMsg, UINT niif_InfoWarningError) { this->h_nid.dwInfoFlags = niif_InfoWarningError; lstrcpy (this->h_nid.szInfo, lpMsg); return (BOOL) Shell_NotifyIcon (NIM_MODIFY, &this->h_nid); } BOOL hNotifyIcon::IsShow () { return (BOOL)this->h_nid.uFlags; }
实现上很简单,和MFC类似,对显示、隐藏、发送泡泡通知等功能进行了封装,需要使用时直接new一个对象出来,简单调用几下就完了。
2.2、ListView / ListCtrl//风格 DWORD dwStyle = ListView_GetExtendedListViewStyle(hList); dwStyle |= LVS_EX_FULLROWSELECT;//选中整行 dwStyle |= LVS_EX_CHECKBOXES;//复选框 ListView_SetExtendedListViewStyle(hList, dwStyle); //添加标头 LV_COLUMN lc; lc.mask = LVCF_TEXT | LVCF_WIDTH; lc.cchTextMax = MAX_PATH; lc.cx = 100; lc.pszText = TEXT("列1"); ListView_InsertColumn(hList, 0, &lc); lc.cx = 100; lc.pszText = TEXT("列2"); ListView_InsertColumn(hList, 1, &lc); …… //添加行 LVITEM li; li.mask = LVIF_TEXT; li.cchTextMax = MAX_PATH; li.iSubItem = 0; li.iItem = 0;//插入第几行,从0开始 li.pszText = TEXT("列1"); ListView_InsertItem(hList, &li); ListView_SetItemText(hList, li.iItem, 1, TEXT("列2")); …… li.iItem = 1; li.pszText = TEXT("列1"); ListView_InsertItem(hList, &li); ListView_SetItemText(hList, li.iItem, 1, TEXT("列2")); …… ……ListView / ListCtrl 的使用就方便多了,一大批 ListView_ 开头的函数,任君选择。
2.3、TabCtrl,也就是所谓的分页控件
分两步,第一步是初始化
#include <CommCtrl.h> hwndTab = GetDlgItem(); hwndChild[0] = CreateDialog(); hwndChild[1] = CreateDialog(); TCITEM ti = { 0 }; ti.mask = TCIF_TEXT; ti.cchTextMax = MAX_PATH; ti.pszText = TEXT("tab1"); TabCtrl_InsertItem(hwndTab, 0, &ti); ti.pszText = TEXT("tab2"); TabCtrl_InsertItem(hwndTab, 1, &ti);第二步,处理WM_NOTIFY消息
case WM_NOTIFY: if (((LOWORD(wParam)) == IDC_TAB_MAIN) && (((LPNMHDR)lParam)->code == TCN_SELCHANGE)) { for(int i=0; i<n; i++) ShowWindow(hwndChild[i], SW_HIDE); ShowWindow(hwndChild[TabCtrl_GetCurSel(hwndTab)], SW_SHOW); } break;简单方便。
这个的实现比较麻烦,我放在云盘,需要的点此下载
有两个压缩包,组件可以直接拿来用,源码可以看看实现方法。另外,XP和Vista就不要试了,系统都没有这个接口的。
2.5、其他Windows常用控件
写一行代码:
#include <windowsx.h>然后点进去,其他该有的都有了,比如RadioButton、CheckBox等等。并不代表所有的都有,SDK界面开发等待着你的发掘。
首先,头文件和库别少,命名空间可以不引用,看个人爱好
#include <Gdiplus.h> #pragma comment(lib, "gdiplus.lib") using namespace Gdiplus;然后,下面代码霸气甩进WinMain开头
ULONG_PTR gdiplusToken; GdiplusStartupInput gdiplusStartupInput; GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);最后,下面代码霸气甩进WinMain返回前
GdiplusShutdown(gdiplusToken);介绍的差不多了。 Win32 博大精深,如有遗漏之处欢迎指正。
原文地址:http://blog.csdn.net/fawdlstty/article/details/45065661