[Win32]富编辑框控件richedit

1.添加头文件,导入库文件;定义控件标识;定义全局的句柄:主窗口,富编辑框控件,lable控件,下拉列表控件;

//添加头文件,导入库文件
#include <richedit.h>
#include <commctrl.h>
#pragma  comment(lib,"comctl32.lib")

//定义控件标识
#define IDC_RICHED_LOGWND               33001
#define IDC_STATIC_POKERSEL             33002
#define IDC_COMBO_POKERSEL             33003

//定义全局的句柄:主窗口,富编辑框控件,lable控件,下拉列表控件
HWND g_hMainWnd=NULL;
HWND g_hLogWnd=NULL;
HWND g_hPokerSelStatic=NULL; 
HWND g_hPokerSelCombo=NULL;

2.在创建完主窗口后,创建子窗体/控件

//   目的: 保存实例句柄并创建主窗口 
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
   HWND hWnd;
   hInst = hInstance; // 将实例句柄存储在全局变量中
   hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
      CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);
   if (!hWnd) {return FALSE;}

   g_hMainWnd = hWnd; // 保存主窗口句柄
   CreateChildWindows();//调用创建子窗体

   ShowWindow(hWnd, nCmdShow);
   UpdateWindow(hWnd);
   return TRUE;
}
//创建子窗口
BOOL CreateChildWindows()
{ 
	// RichEdit,加载dll
	HINSTANCE hRichED = LoadLibrary(_T("riched20.dll"));
	if (hRichED == NULL) 
	{
		return FALSE;
	}
	//创建3个子窗体,富编辑框控件,lable控件,下拉列表控件
	g_hLogWnd = CreateWindow(RICHEDIT_CLASS, NULL,
		WS_CHILD | WS_VSCROLL | WS_HSCROLL | ES_DISABLENOSCROLL | ES_SUNKEN | ES_MULTILINE | ES_READONLY,
		0, 0, 0, 0,
		g_hMainWnd, (HMENU)IDC_RICHED_LOGWND, hInst, NULL); 

        int mask=SendMessage(g_hLogWnd,EM_SETEVENTMASK,0,0);
	SendMessage(g_hLogWnd,EM_SETEVENTMASK,0,ENM_KEYEVENTS | mask);//发送按键消息消息,在父窗体的消息处理函数中捕获按键消息

	g_hPokerSelStatic = CreateWindow(_T("STATIC"), _T("洗牌算法: "),
		WS_CHILD | SS_RIGHT,
		0, 0, 0, 0,
		g_hMainWnd, (HMENU)IDC_STATIC_POKERSEL, hInst, NULL);

	g_hPokerSelCombo = CreateWindow(WC_COMBOBOX, NULL,
		WS_CHILD | WS_VSCROLL | CBS_DROPDOWNLIST | CBS_DISABLENOSCROLL,
		0, 0, 0, 0,
		g_hMainWnd, (HMENU)IDC_COMBO_POKERSEL, hInst, NULL);

	// 设置子窗口字体,弃用系统默认字体
	SendMessage(g_hLogWnd, WM_SETFONT, (WPARAM)GetStockObject(SYSTEM_FIXED_FONT), (LPARAM)FALSE);
	SendMessage(g_hPokerSelStatic, WM_SETFONT, (WPARAM)GetStockObject(DEFAULT_GUI_FONT), (LPARAM)FALSE);
	return TRUE;
}

3.调整子窗口尺寸大小

//  目的: 处理主窗口的消息。 
//  WM_COMMAND	- 处理应用程序菜单
//  WM_PAINT	- 绘制主窗口
//  WM_DESTROY	- 发送退出消息并返回 
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
	int wmId, wmEvent;
	PAINTSTRUCT ps;
	HDC hdc;

	switch (message)
	{
	case WM_COMMAND:
		wmId    = LOWORD(wParam);
		wmEvent = HIWORD(wParam);
		// 分析菜单选择:
		switch (wmId)
		{
		case IDM_ABOUT:
			DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);
			break;
		case IDM_EXIT: 
		    DestroyWindow(hWnd);  
			break;
		default:
			return DefWindowProc(hWnd, message, wParam, lParam);
		}
		break;
	case  WM_NOTIFY://获取富文本框的按键消息
		{
			NMHDR* hdr=(NMHDR*)lParam;
			MSGFILTER * pF = (MSGFILTER *)lParam;
			if(pF->nmhdr.hwndFrom == g_hLogWnd)
			{
				if(pF->msg == WM_KEYDOWN)
				{  
					if(VK_F2 == pF->wParam)
					{                                                
			                        MessageBox(NULL,L"F2",L"快捷键",MB_OK);   
					}  
				}
			} 		
		break; 
		} 
	case WM_SIZE:
		if (wParam != SIZE_MINIMIZED) {
			EnumChildWindows(hWnd, EnumChildWndProc, lParam);//调整子窗口尺寸大小
		} else {
			return DefWindowProc(hWnd, message, wParam, lParam);
		}
		break;
	case WM_PAINT:
		hdc = BeginPaint(hWnd, &ps);
		// TODO: 在此添加任意绘图代码...
		EndPaint(hWnd, &ps);
		break;
	case WM_DESTROY:
		PostQuitMessage(0);
		break;
	default:
		return DefWindowProc(hWnd, message, wParam, lParam);
	}
	return 0;
}
// 调整子窗口尺寸大小
BOOL CALLBACK EnumChildWndProc(HWND hWnd, LPARAM lParam)
{
	int id = GetWindowLong(hWnd, GWL_ID);
	int width = LOWORD(lParam);
	int height = HIWORD(lParam);
	int x = 0;
	int y = 0;
	int cx = 0;
	int cy = 0;

#define MY_STARTX               0
#define MY_STARTY               4
#define MY_CHECKBOX_WIDTH       100
#define MY_BTN_HEIGHT           24
#define MY_BTN_WIDTH            100

	if ((width < MY_BTN_WIDTH) || (height < MY_BTN_HEIGHT)) {
		return FALSE;
	}

	if (id == IDC_STATIC_POKERSEL) {
		x = MY_STARTX;
		y = MY_STARTY + 4;
		cx = 70;
		cy = MY_BTN_HEIGHT - 4; 
	} else if (id == IDC_COMBO_POKERSEL) {
		x = 70;
		y = MY_STARTY;
		cx = 120;
		cy = 160; 
	} else if (id == IDC_RICHED_LOGWND) {
		x = MY_STARTX;
		y = MY_STARTY + MY_BTN_HEIGHT + MY_STARTY;
		cx = width;
		cy = height - (MY_STARTY + MY_BTN_HEIGHT + MY_STARTY);
	} else {
		return TRUE;
	}
	//WriteLog(LOG_INFO, _T("初始化完成,%d,%d开始运行..."),23,45);
	MoveWindow(hWnd, x, y, cx, cy, TRUE);
	ShowWindow(hWnd, SW_SHOW);
	return TRUE;
}

4.写日志函数

// 最多允许一次输出日志的字符数量
#define MAX_LOG_LEN                     256
// 有效的字符数量,(最大值除去回车换行和结束符)
#define VALID_LOG_LEN                   (MAX_LOG_LEN - 3)
static const TCHAR*   s_logLevelString[] = {
	_T("INFO"), _T("WARNING"), _T("ERROR"), _T("DEBUG")
};
void WriteLog(LOG_LEVEL level, TCHAR* fmt, ...)
{
	//if ((level & s_logCurLevel) == 0) { return; }
	if (fmt == NULL) { return; }
	if (level > LOG_DEBUG) { level = LOG_DEBUG; }

	int len = 0;
	int index = 0;
	SYSTEMTIME time = { 0 };
	TCHAR szTime[32] = { 0 };
	TCHAR szLogBuf[MAX_LOG_LEN] = { 0 };

	if (level == LOG_INFO) {
		index = 0;
	} else if (level == LOG_WARN) {
		index = 1;
	} else if (level == LOG_ERROR) {
		index = 2;
	} else if (level == LOG_DEBUG) {
		index = 3;
	}

	GetLocalTime(&time);
	_stprintf_s(szTime, sizeof(szTime) / sizeof(szTime[0]), _T("%04d-%02d-%02d %02d:%02d:%02d"),
		time.wYear, time.wMonth, time.wDay, time.wHour, time.wMinute, time.wSecond);

	// time
	len += _stprintf_s(szLogBuf + len, VALID_LOG_LEN - len, _T("["));
	len += _stprintf_s(szLogBuf + len, VALID_LOG_LEN - len, _T("%s"), szTime);
	len += _stprintf_s(szLogBuf + len, VALID_LOG_LEN - len, _T("]"));

	// log type
	len += _stprintf_s(szLogBuf + len, VALID_LOG_LEN - len,
		_T(" %s: "), s_logLevelString[index]);

	// log message
	va_list va;
	va_start(va, fmt);

	int nStrLen = (int)_vsctprintf(fmt, va);
	if (nStrLen >= MAX_LOG_LEN - 30) {
		index = 1;
		len += _stprintf_s(szLogBuf, VALID_LOG_LEN - len,
			_T(" [WARNING]: MESSAGE TOO LONG TO BE LOGGED!\r\n"));
		va_end(va);
		goto READY_TO_WRITE_LOG;
	}

	len += _vstprintf_s(szLogBuf + len, VALID_LOG_LEN - len, fmt, va);
	va_end(va);

	len += _stprintf_s(szLogBuf + len, VALID_LOG_LEN - len, _T("\r\n"));

READY_TO_WRITE_LOG:
	GETTEXTLENGTHEX gtlex;
	gtlex.codepage = 1200;
	gtlex.flags = GTL_DEFAULT;

	int nCurLen;
	nCurLen = (int)SendMessage(g_hLogWnd, EM_GETTEXTLENGTHEX, (WPARAM)>lex, 0);

	CHARRANGE cr;
	cr.cpMin = nCurLen;
	cr.cpMax = -1;

	// 将文本追加到末尾
	SendMessage(g_hLogWnd, EM_EXSETSEL, 0, (LPARAM)&cr);
	SendMessage(g_hLogWnd, EM_REPLACESEL, (WPARAM)&cr, (LPARAM)szLogBuf);

	// 设置刚追加到末尾的文本的颜色与字符集
	SendMessage(g_hLogWnd, EM_EXSETSEL, 0, (LPARAM)&cr);

	CHARFORMAT cf;
	cf.cbSize = sizeof(CHARFORMAT);
	SendMessage(g_hLogWnd, EM_GETCHARFORMAT, (WPARAM)SCF_SELECTION, (LPARAM)&cf); 
	cr.cpMax = cr.cpMin = -1;
	SendMessage(g_hLogWnd, EM_EXSETSEL, 0, (LPARAM)&cr);

	// 将滚动条移到最底端
	SendMessage(g_hLogWnd, WM_VSCROLL, (WPARAM)SB_BOTTOM, 0);
}
5.效果图

[Win32]富编辑框控件richedit_第1张图片

RichEdit使用手册

你可能感兴趣的:([Win32]富编辑框控件richedit)