1,Win32 Console程序示例:
#include <windows.h>
#include <stdio.h>
#include <string.h>
#include <conio.h>

const int FILEMAX = 300; // allow max. 300 files in each directory

typedef struct _DESTFILE


{//目标文件
WIN32_FIND_DATA fd;
BOOL bMatch;
} DESTFILE;

typedef struct _SRCFILE


{//源文件
WIN32_FIND_DATA fd;
BOOL bIsNew;
} SRCFILE;

int main(int argc, char *argv[])


{
int i, j, iSrcFiles, iDestFiles;
HANDLE hFile;
WIN32_FIND_DATA fd;
BOOL bRet = TRUE;
char src[MAX_PATH+1], dest[MAX_PATH+1], destpath[MAX_PATH+1];
SRCFILE srcFiles[FILEMAX];
DESTFILE destFiles[FILEMAX];
BOOL bFound = FALSE;
DWORD dwcNameSize = MAX_PATH+1;
char szBuffer[MAX_PATH+1];

if (argc < 2)

{
return -1;
}
for (i=0; i< argc; i++)
printf("argv[%d]: %s \n", i, argv[i]);

strcpy(src, argv[1]);
if (argc == 2)

{//未指定目标文件夹
GetCurrentDirectory(dwcNameSize,(LPSTR) &szBuffer);
strcpy(dest, szBuffer);
dest[0] = 'I';//默认目标盘
strcpy(destpath, dest); // destpath should be something like "k:\u002\doc\".
strcat(destpath, "\\"); // just prepare for use latter (when updating and deleting).
strcat(dest, "\\*.*"); // dest should be something like "k:\u002\doc\*.*"
}
else

{//指定目标文件夹
strcpy(destpath, argv[2]); // destpath should be something like "k:"
// just prepare for usage latter (when updating and deleting).
strcpy(dest, argv[2]);
strcat(dest, "*.*"); // then dest should be something like "k:*.*"
}
strcat(src, "*.*"); // src should be something like g:*.*
// prepare srcFiles[]
bRet = TRUE;
iSrcFiles = 0;
// printf("Directory listing of %s\n", src);
hFile = FindFirstFile(src, &fd);
while (hFile != INVALID_HANDLE_VALUE && bRet)

{

if (fd.dwFileAttributes == FILE_ATTRIBUTE_ARCHIVE)
{
srcFiles[iSrcFiles].fd = fd;
srcFiles[iSrcFiles].bIsNew = FALSE;
// printf("%s\n", srcFiles[iSrcFiles].fd.cFileName);
iSrcFiles++;
}
bRet = FindNextFile(hFile, &fd);
}
// prepare destFiles[]
bRet = TRUE;
iDestFiles = 0;
// printf("Directory listing of %s\n", dest);
hFile = FindFirstFile(dest, &fd);
while (hFile != INVALID_HANDLE_VALUE && bRet)

{

if (fd.dwFileAttributes == FILE_ATTRIBUTE_ARCHIVE)
{
destFiles[iDestFiles].fd = fd;
destFiles[iDestFiles].bMatch = FALSE;
// printf("%s\n", destFiles[iDestFiles].fd.cFileName);
iDestFiles++;
}
bRet = FindNextFile(hFile, &fd);
}
// check for new files and redudant files

for (i=0; i<iSrcFiles; i++)
{
bFound = FALSE;

for (j=0; j<iDestFiles; j++)
{

if (!(destFiles[j].bMatch))
{
if (strcmpi(destFiles[j].fd.cFileName, srcFiles[i].fd.cFileName) == 0)

{//找到匹配
// find same files in dest directory
destFiles[j].bMatch = TRUE;
bFound = TRUE;
if (CompareFileTime(&destFiles[j].fd.ftLastWriteTime,
&srcFiles[i].fd.ftLastWriteTime) < 0)

{//比较文件更新时间
// src file is new than dest file
srcFiles[i].bIsNew = TRUE;
}
break; // break j loop, because found!
}
}
}
if (bFound == FALSE) // not found, so is new.
srcFiles[i].bIsNew = TRUE;
}
// updating new files 

for (i=0, j=0; i<iSrcFiles; i++)
{ // j for new files counter

if (srcFiles[i].bIsNew)
{
printf("%s\n", srcFiles[i].fd.cFileName);
j++;
}
}
if (j==0)

{
printf("no file new \n");
}
else

{
printf("There are %d files need to be updated \n", j);
printf("if you do not want to update these files, press Ctrl-Break \n");
printf("otherwise anykey
\n");
getch();
}
for (i=0; i<iSrcFiles; i++)

{
if (srcFiles[i].bIsNew)

{
strcpy(dest, destpath);
strcat(dest, srcFiles[i].fd.cFileName);
CopyFile(srcFiles[i].fd.cFileName, dest, FALSE); // FALSE means overwrite
}
}
// deleting redudant files
for (j=0, i=0; j<iDestFiles; j++)

{ // i for redudant files counter
if (!destFiles[j].bMatch)

{
printf("%s\n", destFiles[j].fd.cFileName);
i++;
}
}
if (i==0)

{
printf("no redudant file \n");
}
else

{
printf("There are %d files need to be deleted \n", i);
printf("if you do not want to delete those files, press Ctrl-Break \n");
printf("otherwise anykey
\n");
getch();
}
for (j=0; j<iDestFiles; j++)

{
if (!destFiles[j].bMatch)

{
strcpy(dest, destpath);
strcat(dest, destFiles[j].fd.cFileName);
DeleteFile(dest);
}
}
return 0;
}

_

2,String型转换为LPWSTR
在TextOut中想直接输出一个string型不行,它参数非得是一个LPWSTR,解决的办法是用MultiByteToWideChar,MultiByteToWideChar 函数可以把普通字符串转换为一个宽字符字符串(Unicode)
LONG OnPaint(HWND hWnd,UINT nMessage,WPARAM wParam,LPARAM lParam)


{
PAINTSTRUCT ps;
HDC hdc;
hdc = BeginPaint(hWnd, &ps);
WCHAR wszMsgInfo[256];
string strInfo = "aa";
MultiByteToWideChar(CP_ACP,0,strInfo.c_str(),strInfo.length(),wszMsgInfo,sizeof(wszMsgInfo)/sizeof(wszMsgInfo[0]));
::TextOut(hdc,10,10,wszMsgInfo,strInfo.length());
EndPaint(hWnd, &ps);
return 0;
}


3,对上一节的代码进行修改,加入一个新的功能,使得能从菜单呼出系统中的记事本
首先修改命令映射表
MSGMAP_ENTRY _commandEntries[] =


{
IDM_ABOUT,OnAbout,
IDM_EXIT,OnExit,
IDM_NOTEBOOK,OnNoteBook
};

再添加一个处理函数,在函数中创建一个记事本进程:
LONG OnNoteBook(HWND hWnd,UINT nMessage,WPARAM wParam,LPARAM lParam)


{
PROCESS_INFORMATION pInfo;
STARTUPINFO si;
ZeroMemory( &si, sizeof(si) );
si.cb = sizeof(si);
ZeroMemory( &pInfo, sizeof(pInfo) );
BOOL bCreated = FALSE;
bCreated = ::CreateProcess(_T("C:\\WINDOWS\\system32\\notepad.exe"),NULL,NULL,NULL,false,0,NULL,NULL,&si,&pInfo);
if(bCreated)
{//割断父子进程间的联系
CloseHandle(pInfo.hProcess);
CloseHandle(pInfo.hThread);
}
return 0;
}

4,新开一个线程获取系统时间
case IDM_GETSYSTIME:


{
DWORD dwThrId;
hSysTime = CreateThread(NULL,0, (LPTHREAD_START_ROUTINE)ReadCurTime,NULL,0,&dwThrId);
if(hSysTime!=NULL)

{
WaitForSingleObject(hSysTime,INFINITE);
CloseHandle(hSysTime);
}
}
break;

void ReadCurTime(void)


{//当前系统时间
SYSTEMTIME st;
GetSystemTime(&st);
char buffer[256];
sprintf(buffer,"%d:%d:%d",st.wYear,st.wMonth,st.wDay);
}

【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· .NET周刊【3月第1期 2025-03-02】
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· [AI/GPT/综述] AI Agent的设计模式综述