Win32编程2-文件写入

4 篇文章 0 订阅

昨天遇到的问题是打开文件选择框后选择文件后程序会直接关闭,这样就无法进行下一步操作,或是取消选择后程序卡死。

经过一段时间的思索,选择文件关闭后程序退出是因为

case WM_COMMAND:
wmId = LOWORD(wParam);
wmEvent = HIWORD(wParam);
switch (wmId)
{
case 1:
OpenDlg(hwnd);
return DefWindowProc(hwnd, message, wParam, lParam);
}

在处理鼠标点击事件时,最下面的return语句应该放到switch外,否则控制权就交还不到windows手里,相当于接收不到下一条消息,程序直接退出。

而取消选择程序卡死是因为没有处理Show函数的返回值

hr = pfd->Show(NULL);       //展示对话框
if (!hr)
{
    MessageBox(hwnd, L"hr", TEXT("warn"), MB_OK);
    IShellItem *pSelItem;
    hr = pfd->GetResult(&pSelItem);     //获取选择的项目
    LPWSTR pszFilePath = NULL;
    //获取文件完整路径
    hr = pSelItem->GetDisplayName(SIGDN_DESKTOPABSOLUTEPARSING, &pszFilePath);
    CoTaskMemFree(pszFilePath);     //释放指针
    pfd->Release();
}

在官方文档查出Show成功运行的返回值是S_OK,就是0,所以判断一下即可,否则后面指针释放异常,按理来说每一步hr都应该判断一下,这里偷个小懒(错误的)。

接下来就是文件内容处理,这里只考虑txt文件。打算再创建一个子窗口,在子窗口里创建一个文本框控件,在里面显示文件内容,然后修改之后再写入文件,在结果在第一个地方就出了问题,关于如何创建子窗口,找了好久才找到,叫模态窗口,原教程作者的写法中有一个地方涉及到long long转换到long,结果在自己编译器上不让转换,去搜了下涉及到的函数,发现不用类型转换,于是换了一种写法,新窗口诞生了,还是一样效率堪忧,面向搜索引擎编程,悲惨的一天。

codeblocks没法调试win32程序。。太蛋疼了,迫不得已转用vs,结果跑不通,原来是long long 转换到 long的那个地方,原作者是对的,我的锅。不该质疑大佬的写法。

以上说的是创建子窗口,原理也好理解,首先停止在当前窗口的操作,就是打开新窗口后无法对旧窗口操作,然后创建新的,最后调用自己写的消息处理函数。

if (pszFilePath != NULL)//如果文件路径不为空
{
EnableWindow(hwnd, FALSE);//停止在当前窗口的操作
//创建新窗口
HWND hwnd1 = CreateWindowEx(NULL, szAppName1, TEXT("文本内容"),
WS_OVERLAPPEDWINDOW & ~WS_MAXIMIZEBOX & ~WS_THICKFRAME,
150, 150, 550, 700,
hwnd, NULL,
hInst,
0
);
if (hwnd1 == NULL)
{
MessageBox(NULL, TEXT("创建窗口失败!"), TEXT("错误"), MB_ICONERROR);
return 0;
}
SetWindowLong(hwnd1, GWLP_WNDPROC, (LONG)&WndProc2);
ShowWindow(hwnd1, 5);
UpdateWindow(hwnd1);
//调用自己写的消息处理函数
ModelWindow(hwnd);
}

下面是用来处理新窗口的消息处理函数,在关闭新窗口后,通过最后两个函数把控制权交还给主窗口。

void ModelWindow(HWND last) {
MSG msg;
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}

EnableWindow(last, TRUE);
SetForegroundWindow(last);
}

这是读取文件的效果图。
vkAKFx.md.png
然后是写入文件

void WriteTxtFile(HWND TxtContent)
{
	HANDLE pfile;
//获取要写入文件的内容大小
	int Editsize = GetWindowTextLength(TxtContent) * 2;
	TCHAR *Data = new TCHAR[Editsize];
//获取要写入内容
	GetWindowText(TxtContent, Data, Editsize);
//打开文件
	pfile = CreateFile(pszFilePath, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if (pfile == INVALID_HANDLE_VALUE)
{
CloseHandle(pfile);
return;
}
DWORD size;
//写入
if (WriteFile(pfile, Data, Editsize, &size, NULL) == 0) {
CloseHandle(pfile);
return;
}
CloseHandle(pfile);
return;
}

写是能写,但是通过WriteFile写入文件或者ReadFile读取后会把文件指针放到文件开头,就是打开txt文件后光标总是在第一位,导致下一次读取时只能读入第一个字符,可能是打开文件模式的问题,但CreateFile的打开模式要么是直接重写,要么是从开头添加新内容,试遍了所有模式光标始终都在第一位,也尝试过用SetFilePointer重设指针位置,但导致了更多的bug,直接放弃了,在读入文件时还会读进来一些奇奇怪怪的东西,明明文件大小没问题,折腾了好几天了,直接弃了,不如进入下一步。

还有个问题就是用char类型读进来,直接显示会乱码,需要转成宽字符BYTE类型,但用BYTE也没法显示中文,直接乱码,不想折腾了,卡在这太久了,直接下一步吧。

按理来说应该都是直接调用api来实现对应功能,速度应该很快,但实际上会遇到很多问题,问题一改就是半天,导致效率过低,一个bug改一天唉。

                                                                                                        2022‎年‎7‎月‎30日

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值