《深入浅出MFC》笔记(三)

简介:
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);
}


本文转自Phinecos(洞庭散人)博客园博客,原文链接:http://www.cnblogs.com/phinecos/archive/2008/01/18/1044929.html,如需转载请自行联系原作者
目录
相关文章
|
机器学习/深度学习 数据可视化 数据处理
OpenAI Gym 高级教程——可解释性和可视化
OpenAI Gym 高级教程——可解释性和可视化
541 1
|
机器学习/深度学习 存储 机器人
LLM系列 | 19: ChatGPT应用框架LangChain实践速成
本文以实践的方式将OpenAI接口、ChatOpenAI接口、Prompt模板、Chain、Agent、Memory这几个LangChain核心模块串起来,从而希望能够让小伙伴们快速地了解LangChain的使用。
|
12月前
|
Web App开发 JavaScript 中间件
构建高效后端服务:Node.js与Express框架的完美结合
【10月更文挑战第21天】本文将引导你走进Node.js和Express框架的世界,探索它们如何共同打造一个高效、可扩展的后端服务。通过深入浅出的解释和实际代码示例,我们将一起理解这一组合的魅力所在,并学习如何利用它们来构建现代Web应用。
334 1
|
12月前
|
域名解析 前端开发 搜索推荐
什么叫CMS?如何使用CMS来制作网站?
PageAdmin CMS,是一套开发了17年,官网还持续在更新和维护的网站内容管理系统,对于领开发的用户来说,对于有网站优化的用户来说,PageAdmin CMS就能帮助我们快速搭建属于自己的个性网站或企业网站。
604 5
|
机器学习/深度学习 算法 TensorFlow
|
SQL 数据处理 数据库
SQL进阶之路:深入解析数据更新与删除技巧——掌握批量操作、条件筛选、子查询和事务处理,提升数据库维护效率与准确性
【8月更文挑战第31天】在数据库管理和应用开发中,数据的更新和删除至关重要,直接影响数据准确性、一致性和性能。本文通过具体案例,深入解析SQL中的高级更新(UPDATE)和删除(DELETE)技巧,包括批量更新、基于条件的删除以及使用子查询和事务处理复杂场景等,帮助读者提升数据处理能力。掌握这些技巧能够有效提高数据库性能并确保数据一致性。
381 0
|
设计模式 JavaScript 前端开发
01. 5 分钟,Vue3 开发快速上手
01. 5 分钟,Vue3 开发快速上手
94 0
|
计算机视觉
halcon系列基础之Scale_image_range
halcon系列基础之Scale_image_range
666 0
|
Web App开发 算法 网络安全
【网络安全 | Misc】解码工具Koczkatamas及CyberChef安装及使用详析
【网络安全 | Misc】解码工具Koczkatamas及CyberChef安装及使用详析
2111 0
|
Go 索引
Go panic & recover 使用注意点:
Go panic & recover 使用注意点:
531 0
Go panic & recover 使用注意点: