[Win32 API学习] Edit,ListBox的用法,字体的设置
[Win32 API学习] Edit,ListBox的用法,字体的设置
Edit相关
Edit里的内容就是它的Text,GetWindowText()啥的函数可以直接用
ListBox的一些消息:
- LB_ADDSTRING:添加字符串(加到listbox最下面),wParam 通常没用,lParam 为指向要添加的字符串的指针
- LB_INSERTSTRING:插入字符串, wParam 为插入位置的行标(从0开始),lParam 为指向要插入的字符串的指针
- LB_DELETESTRING:删除指定位置的字符串,wParam 为要删除的行标,lParam 通常没用
- LB_GETCURSEL:获取当前选中行,wParam 和 lParam 都没用,Sendmessage函数返回选中行的行标,如果没有选中,返回 LB_ERR
- LB_GETCOUNT:返回Listbox中元素个数,wParam 和 lParam 都没用
- LB_GETTEXT:获取某一行的文本,wParam 为行标,lParam 为用来存结果的指针
本来想用ListView的。。结果没学会()
所以最后才会用拼成一个字符串的办法。。。
导致对输入格式有一定要求
结果就是好像还没有notepad好用。。。
所以就当练习了。。。。
字体设置
主要分两步:创建字体、设置字体
- 创建字体CreateFont():参数不是一般的多,建议MSDN;返回字体句柄
- 设置字体SetFont():第一个参数是窗体句柄,第二个参数是字体句柄
其它
- WM_MOVE消息:窗口位置改变时发送,wParam 没用,lParam 的低位是新的x坐标,高位是新的y坐标
- 感觉WCHAR[]和wstring混用不是好习惯
代码
编译需要手动链接gdi32库
#ifndef UNICODE
#define UNICODE
#endif
#ifndef _UNICODE
#define _UNICODE
#endif
#include "sign.h"
#include <windows.h>
#include <fstream>
#include <iostream>
#include <string>
typedef std::wstring wstring;
HINSTANCE hInst;
HWND hMain, hChildWnd;
HWND hList, hButtonAdd, hButtonDel, hButtonMod, hButtonOK, hButtonCancel, hEditEvent, hEditDeadline;
HFONT hFont;
WNDCLASS wcMain, wcChild;
BOOL bModify = false;
INT posx, posy;
LRESULT CALLBACK procMain(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
LRESULT CALLBACK procChild(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
void setFont(HWND hwnd, HFONT h);
void prepare();
void loadData();
void saveData();
void procDel();
void procAdd();
void procModify();
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE, PSTR pCmdLine, INT nCmdShow) {
FreeConsole();
hInst = hInstance;
prepare();
hMain = CreateWindow(L"MainWindow", L"Main", WS_OVERLAPPEDWINDOW ^ WS_SIZEBOX ^ WS_MAXIMIZEBOX, posx = CW_USEDEFAULT,
posy = CW_USEDEFAULT, 700, 300, NULL, NULL, hInst, NULL);
if (!hMain)
MessageBox(NULL, L"Main window creation failed!", L"Error", 0);
ShowWindow(hMain, SW_SHOW);
UpdateWindow(hMain);
MSG msg;
while (GetMessage(&msg, NULL, 0, 0)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return 0;
}
void prepare() {
// 支持中文文件读写(读的必须是GBK编码文件,写出来的也是GBK编码文件)
setlocale(LC_ALL, "chs");
// 主窗口类
wcMain.hInstance = hInst;
wcMain.lpfnWndProc = procMain;
wcMain.lpszClassName = L"MainWindow";
wcMain.style = CS_VREDRAW | CS_HREDRAW;
wcMain.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
wcMain.lpszMenuName = NULL;
wcMain.hCursor = (HCURSOR)LoadCursor(NULL, IDC_ARROW);
// 次级弹出窗口类
wcChild.hInstance = hInst;
wcChild.lpfnWndProc = procChild;
wcChild.lpszClassName = L"ChildWindow";
wcChild.style = CS_VREDRAW | CS_HREDRAW;
wcChild.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
wcChild.lpszMenuName = NULL;
wcChild.hCursor = (HCURSOR)LoadCursor(NULL, IDC_ARROW);
RegisterClass(&wcMain);
RegisterClass(&wcChild);
// 创建字体
hFont = CreateFont(20, 0, 0, 0, FW_DONTCARE, FALSE, FALSE, FALSE, GB2312_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,
DEFAULT_QUALITY, DEFAULT_PITCH | FF_SWISS, L"微软雅黑");
}
LRESULT CALLBACK procMain(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {
switch (msg) {
case WM_DESTROY: {
saveData();
PostQuitMessage(0);
break;
}
case WM_CREATE: {
hList = CreateWindow(L"ListBox", L"", WS_CHILD | WS_VISIBLE | WS_BORDER | WS_VSCROLL, 0, 0, 500, 285, hwnd, (HMENU)IDLB_LISTBOX,
hInst, 0);
// 这里的hwnd不能改成hMain,因为WM_CREATE消息在主函数中的CreateWindow函数结束前发送,此时hMain没有被赋值,为NULL
setFont(hList, hFont);
// 添加、删除、修改按钮
hButtonAdd = CreateWindow(L"Button", L"Add", WS_CHILD | WS_VISIBLE, 550, 20, 100, 30, hwnd, (HMENU)IDB_ADD, hInst, 0);
setFont(hButtonAdd, hFont);
hButtonDel = CreateWindow(L"Button", L"Delete", WS_CHILD | WS_VISIBLE, 550, 80, 100, 30, hwnd, (HMENU)IDB_DEL, hInst, 0);
setFont(hButtonDel, hFont);
hButtonMod = CreateWindow(L"Button", L"Modify", WS_CHILD | WS_VISIBLE, 550, 140, 100, 30, hwnd, (HMENU)IDB_MOD, hInst, 0);
setFont(hButtonMod, hFont);
loadData();
break;
}
case WM_MOVE:
posx = LOWORD(lParam);
posy = HIWORD(lParam);
return DefWindowProc(hwnd, msg, wParam, lParam);
break;
case WM_COMMAND: {
switch (LOWORD(wParam)) {
// 单击添加按钮
case IDB_ADD:
procAdd();
break;
// 单击删除按钮
case IDB_DEL:
procDel();
break;
// 单击修改按钮
case IDB_MOD:
procModify();
break;
default:
return DefWindowProc(hwnd, msg, wParam, lParam);
}
break;
}
default:
return DefWindowProc(hwnd, msg, wParam, lParam);
}
return 0;
}
LRESULT CALLBACK procChild(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {
switch (msg) {
case WM_CREATE: {
// 禁用主窗口
EnableWindow(hMain, false);
// 创建文本框
CreateWindow(L"Static", L"Event:", WS_CHILD | WS_VISIBLE, 20, 20, 120, 25, hwnd, (HMENU)IDT_TEXT1, hInst, 0);
CreateWindow(L"Static", L"Deadline:", WS_CHILD | WS_VISIBLE, 160, 20, 120, 25, hwnd, (HMENU)IDT_TEXT2, hInst, 0);
// 创建编辑框
hEditEvent = CreateWindow(L"Edit", L"", WS_CHILD | WS_VISIBLE | WS_BORDER, 20, 50, 120, 25, hwnd, (HMENU)IDE_EDIT1, hInst, 0);
setFont(hEditEvent, hFont);
hEditDeadline =
CreateWindow(L"Edit", L"", WS_CHILD | WS_VISIBLE | WS_BORDER, 160, 50, 120, 25, hwnd, (HMENU)IDE_EDIT2, hInst, 0);
setFont(hEditDeadline, hFont);
// 创建确认、取消按钮
hButtonOK = CreateWindow(L"Button", L"OK", WS_CHILD | WS_VISIBLE, 25, 80, 100, 30, hwnd, (HMENU)IDB_OK, hInst, 0);
setFont(hButtonOK, hFont);
hButtonCancel = CreateWindow(L"Button", L"Cancel", WS_CHILD | WS_VISIBLE, 175, 80, 100, 30, hwnd, (HMENU)IDB_CANCEL, hInst, 0);
setFont(hButtonCancel, hFont);
if (bModify) {
// 修改模式初始显示原串
WCHAR wcbuf[255];
INT pos = SendMessage(hList, LB_GETCURSEL, 0, 0);
SendMessage(hList, LB_GETTEXT, (WPARAM)pos, (LPARAM)wcbuf);
wstring strd(wcbuf), stre;
int p = strd.find(L'>', 0);
stre = strd.substr(p + 5, strd.length() - p);
strd = strd.substr(1, p - 1);
SetWindowText(hEditEvent, stre.c_str());
SetWindowText(hEditDeadline, strd.c_str());
}
SetFocus(hEditEvent);
break;
}
case WM_COMMAND: {
switch (LOWORD(wParam)) {
case IDB_CANCEL:
SendMessage(hwnd, WM_CLOSE, 0, 0);
break;
case IDB_OK: {
WCHAR wcbuf[255];
wstring strd, stre;
GetWindowText(hEditDeadline, wcbuf, 255);
strd = wcbuf;
if (strd.empty())
strd = L"????????";
GetWindowText(hEditEvent, wcbuf, 255);
stre = wcbuf;
if (bModify) {
// 修改模式
INT pos = SendMessage(hList, LB_GETCURSEL, 0, 0);
SendMessage(hList, LB_DELETESTRING, (LPARAM)pos, 0);
SendMessage(hList, LB_INSERTSTRING, (WPARAM)pos, (LPARAM)(L'<' + strd + L"> " + stre).c_str());
} else {
// 添加模式
SendMessage(hList, LB_ADDSTRING, 0, (LPARAM)(L'<' + strd + L"> " + stre).c_str());
}
SendMessage(hwnd, WM_CLOSE, 0, 0);
break;
}
default:
return DefWindowProc(hwnd, msg, wParam, lParam);
}
break;
}
case WM_CLOSE: {
//启用主窗口
EnableWindow(hMain, true);
DestroyWindow(hwnd);
break;
}
default:
return DefWindowProc(hwnd, msg, wParam, lParam);
}
return 0;
}
inline void setFont(HWND hwnd, HFONT h) { SendMessage(hwnd, WM_SETFONT, (WPARAM)h, TRUE); }
void procDel() {
INT pos = SendMessage(hList, LB_GETCURSEL, 0, 0);
if (pos != LB_ERR)
SendMessage(hList, LB_DELETESTRING, (WPARAM)pos, 0);
}
void procAdd() {
bModify = false;
hChildWnd = CreateWindow(L"ChildWindow", L"Add", WS_OVERLAPPEDWINDOW ^ WS_SIZEBOX ^ WS_MINIMIZEBOX ^ WS_MAXIMIZEBOX, posx + 50,
posy + 50, 300, 150, NULL, NULL, hInst, 0);
ShowWindow(hChildWnd, SW_SHOW);
UpdateWindow(hChildWnd);
}
void procModify() {
bModify = true;
INT pos = SendMessage(hList, LB_GETCURSEL, 0, 0);
if (pos != LB_ERR) {
hChildWnd = CreateWindow(L"ChildWindow", L"Modify", WS_OVERLAPPEDWINDOW ^ WS_SIZEBOX ^ WS_MINIMIZEBOX ^ WS_MAXIMIZEBOX, posx + 50,
posy + 50, 300, 150, NULL, NULL, hInst, 0);
ShowWindow(hChildWnd, SW_SHOW);
UpdateWindow(hChildWnd);
}
}
void loadData() {
// 从文件读入数据并显示
std::wifstream fin("data");
WCHAR wcBuf[255];
while (fin.getline(wcBuf, 255))
SendMessage(hList, LB_ADDSTRING, 0, (LPARAM)wcBuf);
fin.close();
}
void saveData() {
std::wofstream fout("data");
INT cnt = SendMessage(hList, LB_GETCOUNT, 0, 0);
for (int i = 0; i < cnt; ++i) {
WCHAR str[255];
SendMessage(hList, LB_GETTEXT, (WPARAM)i, (LPARAM)str);
fout << str << std::endl;
}
fout.close();
}