今日单词:
Identifier 标识符 识别查明
a count of 数
corresponding 相应的
null-terminated 空字符结尾
retrieve 检索
expires到期,有效期
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消息是由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
#include"resource.h"
#include
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
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 消息中获取 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
#include"resource.h"
#include
//正确的做法是 第一次循环带入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
#include"resource.h"
#include
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的历史来源:
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
#include
#include
#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
*/
#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 扩展窗口样式
*/
#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)
/*
* 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 文本编辑框属性样式
*/
#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 */