VC笔记

来源:互联网 发布:linux select 多线程 编辑:程序博客网 时间:2024/05/28 04:54

对于DIALOG类ONCREATE与ONINITDIALOG的区别

OnCreate是对话框在被创建时的消息,这时候对话框还没有被显示在屏幕上。而且对话框中的控件都还没有被创建。而OnInitDialog()是对话框创建完成,即对话框上的控件也全部被创建后第一次激活显示在屏幕上产生的消息。在此时可以对话框中的控件进行初始化操作。

 

VC注释宏的作用:

VC注释宏是给编译器看的,指示编译器用来填加代码的地方.

 

如何删除一个类:

工程中删除,文件中删除,删除.CLW文件

 

MFC程序执行过程:

 

MFC从APP类的全局变量THE APP进入,调用其父类的构造函数,后调用自已的构造函数.

进入APPMODUL.cpp文件的_tWinMain中,调用Afx'WinMain函数,对于单档结构单线程时pThread指针和pApp指针都是指的APP类,调用了三个函数InitApplication,InitInstance,Run(完成消息映射);

 

Frame框架里面有个PreCreateWindow函数,会在CreateEx创建窗口之前调用,来修改程序外观.


Here are a few facts to note about SetFilePointerEx:

  • Setting a file's pointer beyond the end of the file's current size is legal. Doing so does not actually increase the size of the file on disk unless you write to the file at this position or call SetEndOfFile.

  • When using SetFilePointerEx with a file opened with FILE_FLAG_NO_BUFFERING, the file pointer can be positioned only on sector-aligned boundaries. .

  • Windows does not offer a GetFilePointerEx function, but you can use SetFilePointerEx to move the pointer by 0 bytes to get the desired effect, as shown in the following code snippet:

    LARGE_INTEGER liCurrentPosition = { 0 };
    SetFilePointerEx(hFile, liCurrentPosition, &liCurrentPosition, FILE_CURRENT);

Setting the End of a File

Usually, the system takes care of setting the end of a file when the file is closed. However, you might sometimes want to force a file to be smaller or larger. On those occasions, call

BOOL SetEndOfFile(HANDLE hFile);

This SetEndOfFile function truncates or extends a file's size to the size indicated by the file object's file pointer. For example, if you wanted to force a file to be 1024 bytes long, you'd use SetEndOfFile this way:

HANDLE hFile = CreateFile(...);
LARGE_INTEGER liDistanceToMove;
liDistanceToMove.QuadPart = 1024;
SetFilePointerEx(hFile, liDistanceToMove, NULL, FILE_BEGIN);
SetEndOfFile(hFile);
CloseHandle(hFile);

Flushing Data to the Device

Remember from our look at the CreateFile function that you can pass quite a few flags to alter the way in which the system caches file data. Some other devices, such as serial ports, mailslots, and pipes, also cache data. If you want to force the system to write cached data to the device, you can call FlushFileBuffers:

BOOL FlushFileBuffers(HANDLE hFile);

The FlushFileBuffers function forces all the buffered data associated with a device that is identified by the hFile parameter to be written. For this to work, the device has to be opened with the GENERIC_WRITE flag. If the function is successful, TRUE is returned.

OVERLAPPED结构体中
  • Offset and OffsetHigh When a file is being accessed, these members indicate the 64-bit offset in the file where you want the I/O operation to begin. Recall that each file kernel object has a file pointer associated with it. When issuing a synchronous I/O request, the system knows to start accessing the file at the location identified by the file pointer. After the operation is complete, the system updates the file pointer automatically so that the next operation can pick up where the last operation left off.

    When performing asynchronous I/O, this file pointer is ignored by the system. Imagine what would happen if your code placed two asynchronous calls to ReadFile (for the same file kernel object). In this scenario, the system wouldn't know where to start reading for the second call to ReadFile. You probably wouldn't want to start reading the file at the same location used by the first call to ReadFile. You might want to start the second read at the byte in the file that followed the last byte that was read by the first call to ReadFile. To avoid the confusion of multiple asynchronous calls to the same object, all asynchronous I/O requests must specify the starting file offset in the OVERLAPPED structure.

    Note that the Offset and OffsetHigh members are not ignored for nonfile devices—you must initialize both members to 0 or the I/O request will fail and GetLastError will return ERROR_INVALID_PARAMETER.

overlapped i/o访问时应注意的事情:

you should be aware that the data buffer and OVERLAPPED structure used to issue the asynchronous I/O request must not be moved or destroyed until the I/O request has completed. When queuing an I/O request to a device driver, the driver is passed the address of the data buffer and the address of the OVERLAPPED structure. Notice that just the address is passed, not the actual block. The reason for this should be quite obvious: memory copies are very expensive and waste a lot of CPU time.

When the device driver is ready to process your queued request, it transfers the data referenced by the pvBuffer address, and it accesses the file's offset member and other members contained within the OVERLAPPED structure pointed to by the pOverlapped parameter. Specifically, the device driver updates the Internal member with the I/O's error code and the InternalHigh member with the number of bytes transferred.


Note 

It is absolutely essential that these buffers not be moved or destroyed until the I/O request has completed; otherwise, memory will be corrupted. Also, you must allocate and initialize a unique OVERLAPPED structure for each I/O request.

The preceding note is very important and is one of the most common bugs developers introduce when implementing an asynchronous device I/O architecture. Here's an example of what not to do:

VOID ReadData(HANDLE hFile) {
OVERLAPPED o = { 0 };
BYTE b[100];
ReadFile(hFile, b, 100, NULL, &o);
}

This code looks fairly harmless, and the call to ReadFile is perfect. The only problem is that the function returns after queuing the asynchronous I/O request. Returning from the function essentially frees the buffer and the OVERLAPPED structure from the thread's stack, but the device driver is not aware that ReadData returned. The device driver still has two memory addresses that point to the thread's stack. When the I/O completes, the device driver is going to modify memory on the thread's stack, corrupting whatever happens to be occupying that spot in memory at the time. This bug is particularly difficult to find because the memory modification occurs asynchronously. Sometimes the device driver might perform I/O synchronously, in which case you won't see the bug. Sometimes the I/O might complete right after the function returns, or it might complete over an hour later, and who knows what the stack is being used for then.



原创粉丝点击