首先个人很不喜欢mfc和win32窗口程序,因为工程一旦创建就使用了大量的库,资源等等,太过臃肿。
但有时为了测试一些程序功能,往往又需要一个界面,只要零时使用一下,并不要求有多美观。那么可以用以下方法在控制台程序中弹出UI界面,方便快捷。
1,新建一个资源,Dialog界面,类似于MFC可以随意拖控件,然后会自动生成resource.h文件,包含所有控件的ID。
2,创建窗口回调函数。
BOOL CALLBACK DialogProc(HWND hDlg, UINT wMsg, WPARAM wParam, LPARAM lParam) {
switch(wMsg) {
case WM_INITDIALOG:
g_hMainDlg= hDlg;
//初始化工作,可以用GetDlgItem(hDlg, IDC_XXX)获得控件进行初始化。
return TRUE;
case WM_COMMAND:
CmdProc(hDlg, wMsg, wParam, lParam);//因为是控制台,没有onButtonClick()之类函数,需要由系统发送事件消息判断。
return TRUE; //控件操作的消息都为WM_COMMAND。
case WM_DESTROY:
{ //销毁时的动作,需要销毁加载的资源,如一些图片。
HIMAGELIST himglist = ListView_GetImageList(g_hListThub, LVSIL_NORMAL);
ImageList_Destroy(himglist);
}
return TRUE;
default: break;
}
return FALSE;//返回true表示消息已经完成,不再传递,返回false则继续传递。
}
BOOL CmdProc(HWND hDlg, UINT wMsg, WPARAM wParam, LPARAM lParam)
{
int id = LOWORD(wParam);//触发事件的控件的id
int notifyid = HIWORD(wParam);//事件的id,由于button只考虑了click事件,所以没有深入判断
if (id == IDC_BTN_START) {
GetWindowText(GetDlgItem(hDlg, IDC_XXX), wbuf, 128);//获取字符串
EnableWindow(GetDlgItem(hDlg, id), TRUE);//控制是否禁用
} else if (id == IDC_BTN_EXIT) {
EndDialog(hDlg, 0);//退出
}
else if (id == IDC_BTN_XXX) {
SendDlgItemMessage(hDlg, IDC_LIST_XXX, LB_RESETCONTENT, 0, 0);//清空list控件
int num=10;
for (int i = 0; i < num; i++) {
WCHAR wbuf[128] = L"ListItem";
SendDlgItemMessage(hDlg, IDC_LIST_XXX, LB_ADDSTRING, 0, (LPARAM)wbuf);//向list添加一条文字的命令。
}
}else if (id == IDC_LIST_XXX) {
if (notifyid == LBN_SELCHANGE) { //list中选中的项变化的事件
int isel = SendDlgItemMessage(hDlg, IDC_LIST_XXX, LB_GETCURSEL, 0, 0);//获取选中项的id
if (isel != LB_ERR) {
SendDlgItemMessage(hDlg, IDC_LIST_XXX2, LB_RESETCONTENT, 0, 0); //根据xxx的选中项来更新list_xxx2
int num=10;
for (int i = 0; i < num; i++) {
WCHAR wbuf[128] = L"listItem2";
SendDlgItemMessage(hDlg, IDC_LIST_Devices, LB_ADDSTRING, 0, (LPARAM)wbuf);
}
SendDlgItemMessage(hDlg, IDC_LIST_Devices, LB_SETCURSEL, 0, 0);//设置默认选中id=0的那一项
}
}
}
else if (id == IDC_BTN_XXX2) {
EnableWindow(GetDlgItem(hDlg, id), FALSE);
int isel = SendDlgItemMessage(hDlg, IDC_LIST_XXX2, LB_GETCURSEL, 0, 0);
if (isel != LB_ERR) {
//do Something...
}
EnableWindow(GetDlgItem(hDlg, id), TRUE);
}
else if (id == IDC_BTN_XXX3) {// Initialize GDI+.这里要用到GDI+
Bitmap image(path);
Bitmap *pbmp = ℑ
HIMAGELIST himglist = ImageList_Create(100, 74, ILC_COLOR32 , size, 10);//使用ImageList控件
ListView_SetImageList(g_hListThub, himglist, LVSIL_NORMAL);
ListView_DeleteAllItems(g_hListThub);
HBITMAP hbmImage = NULL; pbmp->GetHBITMAP(Color::Black, &hbmImage); ImageList_Add(himglist, hbmImage, NULL);
LVITEM pitem = {0};
pitem.mask = LVIF_IMAGE | LVIF_TEXT;
pitem.iItem = icnt;
WCHAR wbuf[128] = L"图片说明";
pitem.pszText = wbuf;
pitem.cchTextMax = lstrlen(wbuf);
pitem.iImage = icnt++;
ListView_InsertItem(g_hListThub, &pitem);
}
else if (id == ID_BTN_OpenFile)
{
OPENFILENAME of = {0};
of.lStructSize = sizeof(of);
of.hwndOwner = hDlg;
lstrcpy(wname, file_list[isel].Name);
lstrcpy(wOldname, file_list[isel].Name);
of.lpstrFile = wname;
of.nMaxFile = 256;
LPTSTR pszOpenFilter = TEXT("All Documents (*.*)\0*.*\0\0");
of.lpstrFilter = pszOpenFilter;
of.Flags = 0;
int rc = GetSaveFileName(&of);
if (rc == 0) { return FALSE; }
SetWindowText(GetDlgItem(hDlg, id),wname);
}
return TRUE;
}
其实ListView_InsertItem之类的函数也都是利用SendDlgItemMessage来完成对控件的控制的,只要掌握控件消息,就能像mfc一样完美的控制控件。
3,弹出窗口。
DialogBox(NULL, MAKEINTRESOURCE(IDD_DLG_DLG1), NULL, DlogProc);
只要3步就可以完整的写出一个具有mfc所有特性的窗口程序,一个资源2个函数,是不是很简洁呢。