今天的任务是要保存一个文件。平常看别人怎么写,自己还只是看,没有动手去写过,对各个API相应的参数不是很了解。今天在运用的时候,还真是遇见了一些问题。
我们先来说说问题:
第一个问题:使用WriteFile的时候,我直接将宽字符串写进了文件,文件显示如大家所想,掺杂了很多乱码。但是很有规则。所以我很快就明白了这需要将宽字符串转换成ASCII码。
第二个问题:就是我将文件打开后,又进行了写文件的操作,此时失败。所以对这种情况,还没有想出办法,是由于CreateFile的参数的某些限制么?
由于这两个问题,所以我也好好看了一下SDK文档。
我们先来看一下CreateFile和WriteFile的原型和参数介绍:
HANDLE
CreateFile(
LPCTSTR
lpFileName
, //
文件名
DWORD
dwDesiredAccess
, //
访问方式
DWORD
dwShareMode
, //
共享模式
LPSECURITY_ATTRIBUTES
lpSecurityAttributes
, //
设为NULL
DWORD
dwCreationDisposition
, ///
创建方式
DWORD
dwFlagsAndAttributes
, //
属性
HANDLE
hTemplateFile
);
BOOL
WriteFile(
HANDLE
hFile
, //
文件句柄
LPCVOID
lpBuffer
, //
包含写向文件的数据
DWORD
nNumberOfBytesToWrite
, //
数据包含的字符串的个数
LPDWORD
lpNumberOfBytesWritten
,
LPOVERLAPPED
lpOverlapped
);
第一次我写的程序很简单
BOOL WriteOwnFile(TCHAR* pFileName, TCHAR* pBuffer, DWORD dwLen)
{
HANDLE hFile = CreateFile(pFileName,
GENERIC_WRITE,
FILE_SHARE_WRITE,
NULL,
CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL,
NULL
);
if (INVALID_HANDLE_VALUE != hFile)
{
DWORD dwSize = 0;
WriteFile(hFile, pBuffer, dwLen, &dwSize, NULL );
CloseHandle(hFile);
return TRUE;
}
return FALSE;
}
这样是完成了,但是写出来的文件是乱码。所以没有进行字符的转换,我们需要将pBuffer进行转换。这就要用到了WideCharToMultiByte.如何用呢?
首先我的方法比较笨,我是这么用的:
char* pchBuffer = new char[dwLen+1];
WideCharToMultiByte(CP_ACP, NULL, pBuffer, -1, pchBuffer, dwLen+1, NULL, FALSE );
WriteFile(hFile, pBuffer, dwLen+1, &dwSize, NULL );
Delete[] pchBuffer;
此时注意,我在WriteFile中用了dwLen+1。结果就是在文件的末尾出现了乱码,正好多一个乱码出来。所以WriteFile中nNumberOfBytesToWrite是写的字符串的数目,是不包括’\0’的。
这个方法笨,是因为我们的函数可以缩减为两个参数。是因为如下这么写时,dwLen是所要转换的字符串的个数,此时转换的字符串是包括’\0’的。
DWORD dwLen = WideCharToMultiByte(CP_ACP, NULL, pBuffer, -1, NULL, NULL, NULL, FALSE );
所以我们再来看一下改写以后的代码
BOOL WriteOwnFile(TCHAR* pFileName, TCHAR* pBuffer)
{
HANDLE hFile = CreateFile(pFileName,
GENERIC_WRITE,
FILE_SHARE_WRITE,
NULL,
CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL,
NULL
);
if (INVALID_HANDLE_VALUE != hFile)
{
DWORD dwSize = 0;
DWORD
dwLen = WideCharToMultiByte(CP_ACP, NULL, pBuffer, -1, NULL, NULL,
NULL, FALSE );
char* pchBuffer = new char[dwLen];
WideCharToMultiByte(CP_ACP, NULL, pBuffer, -1, pchBuffer, dwLen, NULL, FALSE );
WriteFile(hFile, pBuffer, dwLen+1, &dwSize, NULL );
delete[] pchBuffer;
CloseHandle(hFile);
return TRUE;
}
return FALSE;
}
这样感觉代码好看多了。
对于第二个问题,文件打开的时候文件创建失败,还没有想好办法解决。我在想是不是我的某些认知存在问题,文件打开的时候,是否可以用CreateFile来打开呢?
补充:
程序的读和写都是自己控制的,所以我在写文件的时候,没有必要进行字符串。读文件的时候也按照相应的字符读取即可。所以我的代码使用最初的代码就可以了。
posted @
2009-02-20 23:59
sandyqy 阅读(291) |
评论 (0)
|
编辑
今天完成了一个任务,就是在mobile上如何监控文件的操作。这个SDK中有相应的例子,为FileChangeNotif。
如何实现文件监控?
首先要在窗口注册,这个要用到SHChangeNotifyRegister
,这个函数的主要功能就是列举一个窗口来接收change notifications.
在这个注册的窗口中,响应WM_FILECHANGEINFO
这个消息,来进行我们响应的操作。
如何我们不想监控了,则可以使用SHChangeNotifyDeregister
,来移除相应的注册窗口。
这样我们就可以实现对一个文件夹内文件的生成,删除,改名等等操作的监控。
下面我们再具体来谈谈每一步如何操作。
1
、SHChangeNotifyRegister
的运用
SHChangeNotifyRegiste
r的原型为
BOOL WINAPI SHChangeNotifyRegister(
HWND hwnd,
SHCHANGENOTIFYENTRY * pshcne
);
其中,hwnd,为接收change notification的窗口;
pshcne
是一个指向SHCHANGENOTIFYENTRY结构的指针,它用来指明窗口接收的change notification的类型.如果设为NULL,窗口将接收all file system, network 和 media类型的notifications.
SHCHANGENOTIFYENTRY
是什么样的一个结构,我们看一下它的定义
typedef struct tagSHCHANGENOTIFYENTRY {
DWORD dwEventMask;
LPTSTR pszWatchDir;
BOOL fRecursive;
} SHCHANGENOTIFYENTRY;
dwEventMask
指定发生什么时间来发送notification 消息
pszWatchDir
指定监控路径,该值为NULL的情况下,是监控所有的文件。
fRecursive
指定是否只监控指定路径还是监控指定路径及其子文件夹。
知道了这些,我们不妨写一个这样的函数,来启动文件监控。
代码如下:
BOOL StartFileMonitor(HWND hWnd, LPTSTR lpFilePath)
{
SHCHANGENOTIFYENTRY schneNotifyEntry;
schneNotifyEntry.dwEventMask = SHCNE_ALLEVENTS;
schneNotifyEntry.pszWatchDir = lpFilePath;
schneNotifyEntry.fRecursive = TRUE;
return SHChangeNotifyRegister(hWnd, &schneNotifyEntry);
}
2
、如何处理WM_FILECHANGEINFO
消息
WM_FILECHANGEINFO 中的参数lParam,指向FILECHANGENOTIFY
,含有相关的数据。所以我们在收到该消息后,先作的一部操作就是
FILECHANGENOTIFY *lpfcn = (FILECHANGENOTIFY*)lParam;
FILECHANGENOTIFY
的结构为:
typedef struct tagFILECHANGENOTIFY {
DWORD dwRefCount;
FILECHANGEINFO fci;
} FILECHANGENOTIFY;
我们主要用到了其中的fci参数。
FILECHANGEINFO
的结构为:
struct _FILECHANGEINFO {
DWORD cbSize;
LONG wEventId;
ULONG uFlags;
DWORD dwItem1;
DWORD dwItem2;
DWORD dwAttributes;
FILETIME ftModified;
ULONG nFileSize;
} FILECHANGEINFO, *LPFILECHANGEINFO;
dwEventId
与SHCHANGENOTIFYENTRY结构中的dwEventMask
对应。
dwItem1,dwItem
2是事件依赖的值,里面包括了我们需要的文件的完整路径。如果是进行创建文件的操作,则dwItem1
是创建后文件的完整路径,如果是对文件进行重新命名操作的话,则dwItem2
是修改后文件的完整路径。此处对其他参数不做介绍,大家需要的话,可以查看一下。
我们做完相应的操作后,要知道释放,此时要用到SHChangeNotifyFree
。这个用起来就简单很多,如SHChangeNotifyFree
(lpfcn)。
下面给大家一小段示例代码,如下
case WM_FILECHANGEINFO:
{
FILECHANGENOTIFY *lpfcn;
FILECHANGEINFO *lpfci;
lpfcn = (FILECHANGENOTIFY *)lParam;
if (NULL == lpfcn)
{
break;
}
// see if the pointer to the file change info structure
lpfci = &(lpfcn->fci);
if (NULL == lpfci)
{
break;
}
else
{
switch (lpfci->wEventId)
{
case SHCNE_RENAME:
{
//……
}
break;
}
}
SHChangeNotifyFree(lpfcn);
}
break;
3
、如何停止文件监控
停止文件监控比较简单,只要使该窗口不接收WM_FILECHANGEINFO
消息即可。使用SHChangeNotifyDeregister(hWnd)
即可。
以上是我今天学习的一些总结,此外需要注意的一个小地方,在mobile上,把一个文件从一个文件夹拷到另一个文件夹,此时响应的事件是
SHCNE_CREATE,二从电脑上拷贝一个文件到mobile上,响应的消息为SHCNE_RENAME。我注意到从电脑上拷贝的话,mobile会
先生成一个Temp文件夹内生成一个临时文件,然后再在我们指定的文件夹内生成一个文件。这个机制我还不是很清楚为什么。
分享到:
相关推荐
windowsmobile手机视频监控软件,目前支持windows mobile 6.1。 实现手机客户端远程监看dvr、dvs、ipc等视频监控设备的实时预览视频;
WindowsMobile5 源码WindowsMobile5 源码WindowsMobile5 源码WindowsMobile5 源码
如何搭建windows mobile应用开发的环境
Windows Mobile开发实验,wince操作系统定制。
众所周知,在windows7操作系统中已经不需要安装active sync ...清您下载windows mobile center for windows7(vista也是如此)软件,然后将手机与电脑连接即可.亲自操作,该方法适合于任何版本的windows mobile 手机系统.
Windows Mobile开发Windows Mobile开发Windows Mobile开发Windows Mobile开发
Windows Mobile for HP iPAQ 114
QR条形码的开发程序,能够在windows mobile 6中实现QR条形码的开发程序,能够在windows mobile 6中实现,eMbedded Visual C++和VS两种源代码
Windows Mobile 经典源码 学习Windows Mobile 的不二选择
windows mobile 6.0 基于WebService方式与PC Server通讯的demo
windows mobile 平台下的My mobile软件。
Windows mobile 6.5常用软件
Windows Mobile应用程序开发介绍 .Windows Mobile平台 .Windows Mobile开发环境搭建 .Windows Mobile开发技术和资源 .Demo
windows mobile直连版
WINDOWS MOBILE滑屏解锁
模拟企业邮件收发,主要是做测试,欢迎下载分享。
windows mobile device center 64位
windows mobile驱动开发
结合经验和实例软件来介绍Windows Mobile操作系统上的短信开发技术
ppc windows mobile rom