MFC开发第三天计时器的应用,记事本拖入文件显示文本文件,Unicode与ANSI编码历史与转换 各种属性样式


三步走:消息-属性-API

今日单词:
Identifier 标识符 识别查明
a count of  数
corresponding  相应的
null-terminated  空字符结尾
retrieve 检索
expires到期,有效期

一、计时器的应用

SetTimer function

SetTimer function

UINT_PTR SetTimer(
  HWND      hWnd,  // 窗口句柄,指定定时器消息将发送到哪个窗口
  UINT_PTR  nIDEvent, // 定时器的标识符,每个定时器必须有一个唯一的标识符
  UINT      uElapse, // 定时器超时时间(毫秒)
  TIMERPROC lpTimerFunc // 指向一个定时器回调函数的指针,每次定时器超时时该函数将被调用
);
参数含义如下:

hWnd:要接收定时器消息的窗口句柄。如果该参数为NULL,则定时器消息将被发送到当前进程的消息队列,并且必须使用GetMessage或PeekMessage函数来检索该消息。
nIDEvent:定时器的标识符,每个定时器必须有一个唯一的标识符。如果在窗口过程中使用SetTimer函数,则该标识符必须在指定的窗口类的WM_TIMER消息处理程序中使用。
uElapse:指定每次定时器超时的时间间隔(毫秒)。当这个时间到达时,SetTimer函数将发送一个WM_TIMER消息到指定的窗口。
lpTimerFunc:一个指向定时器回调函数的指针。每次定时器超时时,该函数将被调用。如果该参数为NULL,则定时器消息将被发送到指定窗口的消息队列中,而不是调用回调函数。

SetTimer(hwndDlg,1,500,NULL);

WM_TIMER message

WM_TIMER消息是由SetTimer函数设置的定时器达到指定的时间间隔后发送给指定窗口的消息。

WM_TIMER message

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    switch (message)
    {
        case WM_CREATE:
            // 创建一个计时器,并将其ID设置为1,间隔为1000毫秒
            SetTimer(hWnd, 1, 1000, NULL);
            break;
        case WM_TIMER:
            // 停止计时器,并执行需要在每个计时器周期内执行的任务
            KillTimer(hWnd, 1);
            // 执行需要在每个计时器周期内执行的任务
            // ...
            // 重新启动计时器
            SetTimer(hWnd, 1, 1000, NULL);
            break;
        case WM_DESTROY:
            // 销毁窗口时停止计时器
            KillTimer(hWnd, 1);
            PostQuitMessage(0);
            break;
        default:
            return DefWindowProc(hWnd, message, wParam, lParam);
    }
    return 0;
}

实际举例如下所示:

#include<windows.h>
#include"resource.h"
#include<stdio.h>

INT_PTR CALLBACK theProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
	switch (uMsg)
	{
	case WM_TIMER:
	{
		RECT rect;
		GetWindowRect(hwndDlg, &rect);
		int nWidth = rect.right - rect.left;
		int nHeight = rect.bottom - rect.top;
		MoveWindow(hwndDlg, rect.left + 2, rect.top+2, nWidth, nHeight, FALSE);
	}
	break;
	case WM_COMMAND:
	{
		switch (LOWORD(wParam))
		{
		case IDCANCEL:
		{
			EndDialog(hwndDlg, 88);
		}
		break;
		case IDC_SETTIMER:
		{
			SetTimer(hwndDlg,1,500,NULL);
		}
		break;
		}
	}
	}
    return FALSE;
}
int WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)
{
    DialogBox(hInstance, (LPCSTR)IDD_MAIN_DLG, NULL, theProc);
    return 0;
}

二、记事本拖入文件显示文本名称

DragQueryFile function

DragQueryFile function

Retrieves the names of dropped files that result from a successful drag-and-drop operation.
函数用于检索拖放文件操作中存储在HDROP结构中的文件路径。

UINT DragQueryFile(HDROP hDrop,UINT iFile,LPTSTR lpszFile,UINT cch);
int nCount = DragQueryFile(hDrop, -1, NULL, 0);
-1返回是拖入文件的总数,否则就是0-n代表第几个文件,输出参数是文件名(完整路径)

UINT DragQueryFile(
  HDROP hDrop,  // 拖曳操作中的数据对象句柄
  UINT iFile,   // 文件索引,从0开始
  LPTSTR lpszFile, //一个指向字符缓冲区的指针,用于接收文件名
  UINT cch  // 指定缓冲区的大小(以字符为单位)
);

WM_DROPFILES

在 WM_DROPFILES 消息中获取 HDROP 句柄。
获取文件数量,使用 DragQueryFile(hDrop, 0xFFFFFFFF, NULL, 0) 获取
遍历文件路径,使用 DragQueryFile(hDrop, i, szFilePath, MAX_PATH) 获取
二进制补码表示法中,0xFFFFFFFF代表的是-1

case WM_DROPFILES:
{
    // 获取 HDROP 句柄
    HDROP hDrop = (HDROP)wParam;
    // 获取文件数量
    UINT nFiles = DragQueryFile(hDrop, 0xFFFFFFFF, NULL, 0);
    // 遍历文件路径
    for (UINT i = 0; i < nFiles; i++)
    {
        TCHAR szFilePath[MAX_PATH];
        DragQueryFile(hDrop, i, szFilePath, MAX_PATH);
        // 输出文件路径
        _tprintf_s(_T("%s\n"), szFilePath);
    }
    // 释放 HDROP 句柄
    DragFinish(hDrop);
    break;
}

实际举例如下所示:

#define  _CRT_SECURE_NO_WARNINGS
#include<windows.h>
#include"resource.h"
#include<stdio.h>
//正确的做法是 第一次循环带入NULL,把需要的长度累加出来,然后new再重新循环再累加。
void onDropFile(HWND hwndDlg, HDROP hDrop)
{
	int nCount = DragQueryFile(hDrop, -1, NULL, 0);
	char s[MAX_PATH];
	char sText[10000]{}; //加上{}后,对sText加上了终止符	
	while (nCount--)
	{
		int n = DragQueryFile(hDrop, nCount, s, MAX_PATH);
		strcat(sText, s);
		strcat(sText, "\r\n");
	}
	SetDlgItemText(hwndDlg, IDC_TEXT, sText);
	DragFinish(hDrop);
}

INT_PTR CALLBACK theProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
	switch (uMsg)
	{
	case WM_DROPFILES:
		MessageBox(hwndDlg, "拖入文件成功", "提示", 0);
		onDropFile(hwndDlg, (HDROP)wParam);
		break;
	case WM_COMMAND:
	{
		switch (LOWORD(wParam))
		{
		case IDCANCEL:
			EndDialog(hwndDlg, 88);
			break;
		}
	}
	}	
	return 0;
}
int WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)
{
	DialogBox(hInstance, (LPCSTR)IDD_MAIN_DLG, NULL, theProc);
	return 0;
}

记事本拖入文件显示文本文件信息

#define  _CRT_SECURE_NO_WARNINGS
#include<windows.h>
#include"resource.h"
#include<stdio.h>
int GetFileSize(FILE* pf)
{
	long m = ftell(pf);
	fseek(pf, 0, SEEK_END);
	long n = ftell(pf);
	fseek(pf, m, SEEK_SET);
	return n;
}
void ReadTextFile(HWND hwndDlg, LPCSTR sFile)
{
	FILE *pf = fopen(sFile, "rb");
	if (!pf)
		return;
	int nSize = GetFileSize(pf);
	if (nSize>0)
	{
		char* p = new char[nSize + 1];
		auto n= fread(p, 1, nSize, pf);
		p[n] = 0;
		SetDlgItemText(hwndDlg, IDC_TEXT, p);
		delete[] p;
	}
	fclose(pf);
}

void onDropFile(HWND hwndDlg, HDROP hDrop)
{	
	char s[MAX_PATH];
	int nCount = DragQueryFile(hDrop, 0, s, sizeof(s));  //取第一个文件名 如果要去最后一个,先求出总数再ncount-1

	//SetDlgItemText(hwndDlg, IDC_TEXT, s);
	ReadTextFile(hwndDlg, s);
	DragFinish(hDrop);
}

INT_PTR CALLBACK theProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
	switch (uMsg)
	{
	case WM_DROPFILES:
		MessageBox(hwndDlg, "拖入文件成功", "提示", 0);
		onDropFile(hwndDlg, (HDROP)wParam);
		break;
	case WM_COMMAND:
	{
		switch (LOWORD(wParam))
		{
		case IDCANCEL:
			EndDialog(hwndDlg, 88);
			break;
		}
	}
	}
	return 0;
}
int WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)
{
	DialogBox(hInstance, (LPCSTR)IDD_NOTE_DLG, NULL, theProc);
	return 0;
}

三、 Unicode与ANSI编码历史与转换

Unicode的历史来源:
a)MB代表ANSI,为什么ANSI叫做多字节?多种国家的编码混合体,英文单字节,其他国家全部是双字节。
b)WideChar叫做宽字符:第一个版本的Unicode,把包括英文在内所有国家都进行了统一编码,并且都是双字节。
c)早期的类型typedef short wchar_t;高级的VS中wchar_t和char都属于基本类型。
d)WideChar又升级一种Utf-8,原有的WideChar也可以称之为Utf-16.
e)Utf-8才是真正的多字节编码,为什么呢?因为英文1个字节,其他国家又2-4个字节。

Utf-8和ANSI都叫做MultiByte多字节文字编码。

Win32 API提供了一些函数来转换文本编码。下面是一些常用的转换函数:
MultiByteToWideChar:将ANSI编码的文本转换为Unicode编码的文本
WideCharToMultiByte:将Unicode编码的文本转换为ANSI或Utf-8编码的文本

MultiByteToWideChar和WideCharToMultiByte的组合:将ANSI编码的文本转换为UTF-8编码的文本

#include <stdio.h>
#include <windows.h>
#include <locale.h>
#define BUFF_SIZE 1024
  
wchar_t * ANSIToUnicode( const char* str )
{
     int textlen ;
     wchar_t * result;
     textlen = MultiByteToWideChar( CP_ACP, 0, str,-1, NULL,0 );
     result = (wchar_t *)malloc((textlen+1)*sizeof(wchar_t));
     memset(result,0,(textlen+1)*sizeof(wchar_t));
     MultiByteToWideChar(CP_ACP, 0,str,-1,(LPWSTR)result,textlen );
     return result;
}
  
char * UnicodeToANSI( const wchar_t* str )
{
     char* result;
     int textlen;
     textlen = WideCharToMultiByte( CP_ACP, 0, str, -1, NULL, 0, NULL, NULL );
     result =(char *)malloc((textlen+1)*sizeof(char));
     memset( result, 0, sizeof(char) * ( textlen + 1 ) );
     WideCharToMultiByte( CP_ACP, 0, str, -1, result, textlen, NULL, NULL );
     return result;
}
  
wchar_t * UTF8ToUnicode( const char* str )
{
     int textlen ;
     wchar_t * result;
     textlen = MultiByteToWideChar( CP_UTF8, 0, str,-1, NULL,0 );
     result = (wchar_t *)malloc((textlen+1)*sizeof(wchar_t));
     memset(result,0,(textlen+1)*sizeof(wchar_t));
     MultiByteToWideChar(CP_UTF8, 0,str,-1,(LPWSTR)result,textlen );
     return result;
}
  
char * UnicodeToUTF8( const wchar_t* str )
{
     char* result;
     int textlen;
     textlen = WideCharToMultiByte( CP_UTF8, 0, str, -1, NULL, 0, NULL, NULL );
     result =(char *)malloc((textlen+1)*sizeof(char));
     memset(result, 0, sizeof(char) * ( textlen + 1 ) );
     WideCharToMultiByte( CP_UTF8, 0, str, -1, result, textlen, NULL, NULL );
     return result;
}
/*宽字符转换为多字符Unicode - ANSI*/
char* w2m(const wchar_t* wcs)
{
      int len;
      char* buf;
      len =wcstombs(NULL,wcs,0);
      if (len == 0)
          return NULL;
      buf = (char *)malloc(sizeof(char)*(len+1));
      memset(buf, 0, sizeof(char) *(len+1));
      len =wcstombs(buf,wcs,len+1);
      return buf;
}
/*多字符转换为宽字符ANSI - Unicode*/
wchar_t* m2w(const char* mbs)
{
      int len;
      wchar_t* buf;
      len =mbstowcs(NULL,mbs,0);
      if (len == 0)
          return NULL;
      buf = (wchar_t *)malloc(sizeof(wchar_t)*(len+1));
      memset(buf, 0, sizeof(wchar_t) *(len+1));
      len =mbstowcs(buf,mbs,len+1);
      return buf;
}
  
char* ANSIToUTF8(const char* str)
{
     return UnicodeToUTF8(ANSIToUnicode(str));
}
  
char* UTF8ToANSI(const char* str)
{
     return UnicodeToANSI(UTF8ToUnicode(str));
}
  
int main()
{
     /*使用wcstombs和mbstowcs之前必须调用setlocale,以便决定内码*/
     setlocale(LC_ALL,".936");
     /*假定有一个Unicode(UTF-16LE)编码的文件,将其打开,重新编码为ANSI
,写入aa.txt中,再继续编码回Unicode,写入aw.txt中*/
     /*如果不存在a.txt文件,则程序出错,没有做错误处理*/
     char* filename = "a.txt";
     char* filenamea = "aa.txt";
     char* filenamew = "aw.txt";
     FILE*     input=fopen( filename, "rb");
     FILE*     inputa=fopen( filenamea, "wb");
     FILE*     inputw=fopen( filenamew, "wb");
     wchar_t * buf ;
     /*BOE设置,UTF-16LE的BOE为FEFF,如果不先将其读取出来,wcstombs会调用失败*/
     fgetwc(input);
     fputwc(0xFEFF,inputw);
     /*开始读取文件*/
     while(!feof(input))
     {
        buf = (wchar_t *)malloc(sizeof(wchar_t)*BUFF_SIZE)         ;
        memset(buf,    0, sizeof(wchar_t) * BUFF_SIZE );
        fgetws(buf,    BUFF_SIZE,    input);
        fputs(w2m(buf),    inputa);
        fputws(m2w(w2m(buf)),    inputw);
     }
     /*后续处理*/
     fclose(input);
     fclose(inputa);
     fclose(inputw);
     free(buf);
  
     return 0;
}

四、属性样式

Window Styles


/*
 * Window Styles
 */
#define WS_OVERLAPPED       0x00000000L
#define WS_POPUP            0x80000000L
#define WS_CHILD            0x40000000L
#define WS_MINIMIZE         0x20000000L
#define WS_VISIBLE          0x10000000L
#define WS_DISABLED         0x08000000L
#define WS_CLIPSIBLINGS     0x04000000L
#define WS_CLIPCHILDREN     0x02000000L
#define WS_MAXIMIZE         0x01000000L
#define WS_CAPTION          0x00C00000L     /* WS_BORDER | WS_DLGFRAME  */
#define WS_BORDER           0x00800000L
#define WS_DLGFRAME         0x00400000L
#define WS_VSCROLL          0x00200000L
#define WS_HSCROLL          0x00100000L
#define WS_SYSMENU          0x00080000L
#define WS_THICKFRAME       0x00040000L
#define WS_GROUP            0x00020000L
#define WS_TABSTOP          0x00010000L

#define WS_MINIMIZEBOX      0x00020000L
#define WS_MAXIMIZEBOX      0x00010000L


#define WS_TILED            WS_OVERLAPPED
#define WS_ICONIC           WS_MINIMIZE
#define WS_SIZEBOX          WS_THICKFRAME
#define WS_TILEDWINDOW      WS_OVERLAPPEDWINDOW

Extended Window Styles 扩展窗口样式

/*
 * Extended Window Styles 扩展窗口样式
 */
#define WS_EX_DLGMODALFRAME     0x00000001L 模式边框
#define WS_EX_NOPARENTNOTIFY    0x00000004L
#define WS_EX_TOPMOST           0x00000008L 最顶端(窗口置顶)
#define WS_EX_ACCEPTFILES       0x00000010L 接受文件
#define WS_EX_TRANSPARENT       0x00000020L
#if(WINVER >= 0x0400)
#define WS_EX_MDICHILD          0x00000040L  多文档(在第十二章)
#define WS_EX_TOOLWINDOW        0x00000080L 工具窗口
#define WS_EX_WINDOWEDGE        0x00000100L 
#define WS_EX_CLIENTEDGE        0x00000200L 深下陷
#define WS_EX_CONTEXTHELP       0x00000400L

#endif /* WINVER >= 0x0400 */
#if(WINVER >= 0x0400)

#define WS_EX_RIGHT             0x00001000L
#define WS_EX_LEFT              0x00000000L
#define WS_EX_RTLREADING        0x00002000L
#define WS_EX_LTRREADING        0x00000000L
#define WS_EX_LEFTSCROLLBAR     0x00004000L
#define WS_EX_RIGHTSCROLLBAR    0x00000000L

#define WS_EX_CONTROLPARENT     0x00010000L
#define WS_EX_STATICEDGE        0x00020000L  浅下陷
#define WS_EX_APPWINDOW         0x00040000L


#define WS_EX_OVERLAPPEDWINDOW  (WS_EX_WINDOWEDGE | WS_EX_CLIENTEDGE)
#define WS_EX_PALETTEWINDOW     (WS_EX_WINDOWEDGE | WS_EX_TOOLWINDOW | WS_EX_TOPMOST)

SW(Show Windows)样式


/*
 * ShowWindow() Commands
 */
#define SW_HIDE             0
#define SW_SHOWNORMAL       1
#define SW_NORMAL           1
#define SW_SHOWMINIMIZED    2
#define SW_SHOWMAXIMIZED    3
#define SW_MAXIMIZE         3
#define SW_SHOWNOACTIVATE   4
#define SW_SHOW             5
#define SW_MINIMIZE         6
#define SW_SHOWMINNOACTIVE  7
#define SW_SHOWNA           8
#define SW_RESTORE          9
#define SW_SHOWDEFAULT      10
#define SW_FORCEMINIMIZE    11
#define SW_MAX              11


/*
 * Old ShowWindow() Commands
 */
#define HIDE_WINDOW         0
#define SHOW_OPENWINDOW     1
#define SHOW_ICONWINDOW     2
#define SHOW_FULLSCREEN     3
#define SHOW_OPENNOACTIVATE 4

Edit Control Styles 文本编辑框属性样式

/*
 * Edit Control Styles  文本编辑框属性样式
 */
#define ES_LEFT             0x0000L 
#define ES_CENTER           0x0001L
#define ES_RIGHT            0x0002L
以上是对齐方式
#define ES_MULTILINE        0x0004L 多行
#define ES_UPPERCASE        0x0008L  大写
#define ES_LOWERCASE        0x0010L 小写
#define ES_PASSWORD         0x0020L 密码
#define ES_AUTOVSCROLL      0x0040L 自动横滚(跟自动换行有关)
#define ES_AUTOHSCROLL      0x0080L 自动竖直滚动
#define ES_NOHIDESEL        0x0100L 不隐藏选择
#define ES_OEMCONVERT       0x0400L 
#define ES_READONLY         0x0800L 只读属性

#define ES_WANTRETURN       0x1000L 回车换行(默认是Ctrl+回车换行)
#if(WINVER >= 0x0400)
#define ES_NUMBER           0x2000L 不接受数字以外的
#endif /* WINVER >= 0x0400 */
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Jcrry

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值