標籤:c++ sdk 介面 控制項 gdi+
對於不習慣用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);elselstrcpy ((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;簡單方便。
2.4、工作列進度條
這個的實現比較麻煩,我放在雲端硬碟,需要的點此下載
有兩個壓縮包,組件可以直接拿來用,源碼可以看看實現方法。另外,XP和Vista就不要試了,系統都沒有這個介面的。
2.5、其他Windows常用控制項
寫一行代碼:
#include <windowsx.h>
然後點進去,其他該有的都有了,比如RadioButton、CheckBox等等。並不代表所有的都有,SDK介面開發等待著你的發掘。
3、C++/SDK 調用 Gdiplus
有了標準控制項,總不能沒有繪圖吧?GDI太渣,又麻煩又複雜又不支援png還有鋸齒。我在這兒簡要說說如何引用Gdiplus。
首先,標頭檔和庫別少,命名空間可以不引用,看個人愛好
#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 博大精深,如有遺漏之處歡迎指正。
C++/SDK介面開發總結