笔记01

8 篇文章 0 订阅

SHGetPathFromIDList

 

AfxSetResourceHandle

AfxSetResourceHandle

 

GetEnvironmentVariable

SetEnvironmentVariable

 

PathFindFileName

PathRemoveExtension

 

PathIsDirectory

 

PathFileExists

 

切分依据:

DragQueryFile中获得的路径是'\'分格(PS:WinAPI中大部分都是这种,QT中有2种一种是“\\”一种是“/”)

BOOL FilePathSplit( const CString & strFileAllName,CString &strPathName,CString &strFileName )
{
	int nPos = strFileAllName.ReverseFind(TEXT('\\'));
	if(nPos == -1) return FALSE;
	strFileName = strFileAllName.Mid(nPos + 1);
	strPathName = strFileAllName.Left(nPos);
	return TRUE;	
}

PathRemoveFileSpecW

PathRemoveFileSpec函数的作用是将路径末尾的文件名和反斜杠去掉。

例如:

#include <stdio.h>
#include <Shlwapi.h>
 
int main(int argc, char *argv[])
{
    char szSelf[MAX_PATH];
 
    GetModuleFileName(NULL, szSelf, MAX_PATH);
    PathRemoveFileSpec(szSelf);
    printf("%s\n", szSelf);
 
    return 0;
}

 

CoTaskMemFree

https://blog.csdn.net/gaoxiaowei/article/details/5701789

 

offsetof

 

 

SHGetMalloc

 

SetWindowsHookEx

 

CStringW::ReleaseBuffer

 

EnumThreadWindows()

 

SHBrowseForFolder

 

SetWindowPos

SubclassWindow

 

VirtualFree

VirtualFree
释放,decommits,或释放和decommits区域的页在调用进程的虚拟地址空间。
在另一个释放内存的分配过程virtualallocex函数的使用virtualfreeex功能。
BOOL WINAPI VirtualFree(
  _In_ LPVOID lpAddress,
  _In_ SIZE_T dwSize,
  _In_ DWORD  dwFreeType
);
参数

lpaddress[在]
    一个指向要释放的页面区域的基本地址的指针。
    如果dwFreeType参数是MEM_RELEASE,则该参数必须是虚拟分配函数在保留页面区域时返回的基本地址。
dwSize [in]
    要释放的内存区域的大小,以字节为单位。
    如果dwFreeType参数是MEM_RELEASE,则该参数必须为0(0)。该函数释放初始分配调用VirtualAlloc时保留的整个区域。
    如果dwFreeType参数是MEM_DECOMMIT,则该函数将分解从lpAddress参数到(lpAddress+dwSize)范围内包含一个或多个字节的所有内存页。例如,这意味着跨页面边界的2字节内存区域会导致两个页面都被取消传输。如果lpAddress是VirtualAlloc返回的基地址,dwSize为0(0),则函数分解VirtualAlloc分配的整个区域。之后,整个区域处于保留状态。
dwFreeType [in]
    自由操作的类型。该参数可以是下列值之一。
   MEM_DECOMMIT    
    分解提交页的指定区域。操作完成后,页面处于保留状态。
    如果尝试对未提交的页面进行反编译,则该函数不会失败。这意味着您可以在不确定当前承诺状态的情况下分解一系列页面。
    不要在MEM_RELEASE中使用这个值。
    当lpAddress参数为飞地提供基地址时,不支持MEM_DECOMMIT值。
   MEM_RELEASE
    释放页面的指定区域。在此操作之后,页面处于空闲状态。
    如果指定这个值,dwSize必须为0 (0),lpAddress必须指向保留区域时VirtualAlloc函数返回的基地址。如果不满足这两个条件之一,函数将失败。
    如果当前提交了该区域中的任何页面,该函数首先进行分解,然后释放它们。
    如果您试图释放处于不同状态的页面(有些是保留的,有些是提交的),该函数不会失败。这意味着您可以在不确定当前承诺状态的情况下发布一系列页面。
    不要在MEM_DECOMMIT中使用这个值。
返回值

如果函数成功,返回值是非零的。

如果函数失败,返回值为0(0)。要获得扩展错误信息,请调用GetLastError。

Remarks

进程虚拟地址空间中的每个内存页都有一个页状态。VirtualFree函数可以分解处于不同状态的一系列页面,有些页面已提交,有些页面未提交。这意味着您可以分解一系列页面,而无需首先确定每个页面的当前承诺状态。解除分页将释放其物理存储,这些物理存储可能位于内存中,也可能位于磁盘上的分页文件中。

如果一个页面被取消访问,但没有被释放,那么它的状态将更改为保留。随后,您可以调用VirtualAlloc提交它,或者调用VirtualFree发布它。试图从保留页读取或写入保留页会导致访问冲突异常。

VirtualFree函数可以释放一系列处于不同状态的页面,有些是保留的,有些是提交的。这意味着您可以发布一系列页面,而无需首先确定每个页面的当前承诺状态。必须同时释放VirtualAlloc函数最初保留的所有页面。

如果一个页面被释放,它的状态将变为free,并且可以用于后续的分配操作。内存释放或解压后,再也不能引用内存。任何可能存在于记忆中的信息都将永远消失。试图从自由页读取或写入自由页会导致访问冲突异常。如果需要保存信息,请不要分解或释放包含该信息的内存。

可以在AWE内存区域上使用VirtualFree函数,当释放地址空间时,它会使该区域中的任何物理页面映射失效。但是,物理页面没有被删除,应用程序可以使用它们。应用程序必须显式调用FreeUserPhysicalPages来释放物理页面。当进程终止时,所有资源将自动清理。

若要在使用完飞地后删除飞地,请指定以下值:

lpAddress参数的enclave的基本地址。

dwSize参数为0。

用于dwFreeType参数的MEM_RELEASE。对于enclave不支持MEM_DECOMMIT值。

        HeapCreate

HeapCreate

这个函数创建一个只有调用进程才能访问的私有堆。进程从虚拟地址空间里保留出一个连续的块并且为这个块特定的初始部分分配物理空间。


HANDLE HeapCreate(DWORD flOptions , DWORD dwInitialSize , DWORD dwMaxmumSize);

参数:

flOptions:堆的可选属性。这些标记影响以后对这个堆的函数操作,函数有:HeapAlloc , HeapFree , HeapReAlloc , HeapSize .

下面给_出在此可以指定的标记:

HEAP_NO_SERIALIAZE:指定当函数从堆里分配和释放空间时不互斥(不使用互斥锁)。当不指定该标记时默认为使用互斥。序列化允许多个线程操作同一个堆而不会错误。这个标记是可忽略的。

HEAP_SHARED_READONLY:这个标记指定这个堆只能由创建它的进程进行写操作,对其他进程是只读的。如果调用者不是可靠的,调用将会失败,错误代码ERROR_ACCESS_DENIDE 。

注解:为了使用标记为HEAP_SHARED_READONLY的堆,运行在kernel mode(核心状态)是必须的。

dwInitialSize:堆的初始大小,单位为Bytes。这个值决定了分配给堆的初始物理空间大小。这个值将向上舍入知道下个page boundary(页界)。若需得到主机的页大小,使用GetSystemInfo 函数。

dwMaxmumSize:如果该参数是一个非零的值,它指定了这个堆的最大大小,单位为Bytes。该函数会向上舍入该值直到下个页界,然后为这个堆在进程的虚拟地址里保留舍入后大小的块。如果函数 HeapAlloc 和 HeapReAlloc 要求分配的空间超过参数 dwInitialSize 指定的大小,系统会分配额外的空间给该堆直到这个堆的最大大小。If dwMaximumSize is nonzero, the heap cannot grow and an absolute limitation arises where all allocations are fulfilled within the specified heap unless there is not enough free space. (如果该参数非零,除非没有足够的空间,这个堆总可以增长到该大小)。如果该参数为零,那么该堆大小的唯一限制是可用的内存空间。分配大小超过 0x0018000 Bytes的空间总会失败,因为获得这么大的空间需要系统调用 VirtualAlloc 函数。需要使用大空间的应用应该把该参数设置为零。

返回值:

成功:一个指向新创建的堆的指针。

失败:NULL

调用函数 GetLastError 获得更多的错误信息。

附注:

这个函数在调用进程里创建一个私有堆,进程可调用 HeapAlloc 函数分配内存空间。这些页在进程的虚拟空间内创建了一个块,在那里堆可以增长。

如果 HeapAlloc 函数请求的空间超过了现有的页大小,如果物理空间足够的话,额外的空间将会从已保留的空间里附加。

只有创建私有堆的进程可以访问私有堆。

如果一个DLL(动态链接库)创建了一个私有堆,那么这么私有堆是在调用该DLL的进程的地址空间内,且仅该进程可访问。

系统会使用私有堆的一部分空间去储存堆的结构信息,所以,不是所有的堆内空间对进程来说是可用的。例如:HeapAlloc函数从一个最大大小为 64KB 的堆里申请 64KB 的空间,由于系统占用的一部分空间,这个请求通常会失败。

要求:

系统版本:WinCE 1.0 以上。

头文件:Winbase.h

链接库:Coredll.lib
转自:https://blog.csdn.net/windroid/article/details/42302519

SecureZeroMemory

secureZeroMemory和ZeroMerory的区别

    根据MSDN上,ZeryMerory在当缓冲区的字符串超出生命周期的时候,会被编译器优化,从而缓冲区的内容会被恶意软件捕捉到。
引起软件安全问题,特别是对于密码这些比较敏感的信息而说。
而SecureZeroMemory则不会引发此问题,保证缓冲区的内容会被正确的清零。如
果涉及到比较敏感的内容,尽量使用SecureZeroMemory函数。

atlensure

此功能用于验证所传递的参数的函数。
ATLENSURE(booleanExpression);
ATLENSURE_THROW(booleanExpression, hr);
参数

    booleanexpression
    指定的布尔表达式被测试。

    HR
    返回一个指定错误代码。

备注

这些宏提供机制来检测并通知用户不正确的参数使用。

宏调用atlassert并且如果条件失败时调用atlthrow。

在atlensure情况下,atlthrow用E_FAIL。

在atlensure_扔情况下,atlthrow用指定的HRESULT。

之间的区别atlensure和atlassert是,atlensure抛出一个异常在发布版本和调试版本。

InitializeCriticalSectionAndSpinCount

初始化临界段对象并设置临界段的自旋计数。
当线程试图获取被锁定的临界区时,线程会自旋:它进入一个循环,循环迭代自旋计数,检查是否释放锁。
如果锁在循环结束之前没有释放,线程将进入休眠状态,等待释放锁。

#ifndef _CRTDBG_MAP_ALLOC
    #define _CRTDBG_MAP_ALLOC
#endif

_CRTDBG_MAP_ALLOC调用VS自带内存检测泄露工具 
https://blog.csdn.net/fengbingchun/article/details/51114925
https://blog.csdn.net/chenyujing1234/article/details/8075667

来自HP-Socket例子:
win32_crtdbg.h:
/*
 * Copyright: JessMA Open Source (ldcsaa@gmail.com)
 *
 * Author	: Bruce Liang
 * Website	: http://www.jessma.org
 * Project	: https://github.com/ldcsaa
 * Blog		: http://www.cnblogs.com/ldcsaa
 * Wiki		: http://www.oschina.net/p/hp-socket
 * QQ Group	: 75375912, 44636872
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
 
#pragma once

#if defined _DEBUG && defined _DETECT_MEMORY_LEAK

#ifdef new
	#undef new
#endif

#ifdef delete
	#undef delete
#endif

#ifndef _CRTDBG_MAP_ALLOC
	#define _CRTDBG_MAP_ALLOC
#endif

#include <crtdbg.h>

namespace __dbg_impl
{
	class CDebugEnv
	{
	public:
		CDebugEnv()
		{
			::_CrtSetDbgFlag( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF );
			::_CrtMemCheckpoint(&s1);
		}

		~CDebugEnv()
		{
			::_CrtMemCheckpoint(&s2);

			if (::_CrtMemDifference( &s3, &s1, &s2))
			{
				TRACE("!! Memory stats !!\n");
				TRACE("----------------------------------------\n");
				::_CrtMemDumpStatistics(&s3);
				TRACE("----------------------------------------\n");
			}
		}

	private:
		_CrtMemState s1, s2, s3;
	};

	static __dbg_impl::CDebugEnv __dbgEnv;
}

#pragma warning(push)
#pragma warning(disable: 4595)

inline void* __cdecl operator new(size_t nSize, const char* lpszFileName, int nLine)
{
	// __dbg_impl::CGuard guard;
	return ::_malloc_dbg(nSize, _NORMAL_BLOCK, lpszFileName, nLine);
}

inline void* __cdecl operator new[](size_t nSize, const char* lpszFileName, int nLine)
{
	return operator new(nSize, lpszFileName, nLine);
}

inline void* __cdecl operator new(size_t nSize)
{
	return operator new(nSize, __FILE__, __LINE__);
}

inline void* __cdecl operator new[](size_t nSize)
{
	return operator new(nSize, __FILE__, __LINE__);
}

inline void* __cdecl operator new(size_t nSize, const std::nothrow_t&)
{
	return operator new(nSize, __FILE__, __LINE__);
}

inline void* __cdecl operator new[](size_t nSize, const std::nothrow_t&)
{
	return operator new(nSize, __FILE__, __LINE__);
}

inline void __cdecl operator delete(void* p)
{
	// __dbg_impl::CGuard guard;
	::_free_dbg(p, _NORMAL_BLOCK);
}

inline void __cdecl operator delete[](void* p)
{
	operator delete(p);
}

inline void __cdecl operator delete(void* p, const char* lpszFileName, int nLine)
{
	operator delete(p);
}

inline void __cdecl operator delete[](void* p, const char* lpszFileName, int nLine)
{
	operator delete(p);
}

inline void __cdecl operator delete(void *p, const std::nothrow_t&)
{
	operator delete(p);
}

inline void __cdecl operator delete[](void *p, const std::nothrow_t&)
{
	operator delete(p);
}

#pragma warning(pop)

#define new new(__FILE__, __LINE__)

#endif // _DEBUG && defined _DETECT_MEMORY_LEAK









win32_crtdbg.cpp:

#include "stdafx.h"
#include "win32_crtdbg.h"

#if defined _DEBUG && defined _DETECT_MEMORY_LEAK

__dbg_impl::CDebugEnv __dbgEnv;

#endif // _DEBUG && defined _DETECT_MEMORY_LEAK



#pragma intrinsic(_ReadBarrier)
#pragma intrinsic(_WriteBarrier)
#pragma intrinsic(_ReadWriteBarrier)


//限制可以跨调用点重新排序内存访问操作的编译器优化。
//_ReadBarrier、_WriteBarrier和_ReadWriteBarrier编译器内部函数以及MemoryBarrier宏都是不赞成使用的。
//对于线程间通信,可以使用atomic_thread_fence和std::atomic等机制,这些机制是在c++标准库中定义的。
//对于硬件访问,使用 / volatile:iso编译器选项以及volatile关键字。 by MSDN 2016.11

_malloc_dbg

在具有额外空间的堆中为调试标头和覆盖缓冲区分配内存块(仅限调试模式)。
void *_malloc_dbg(
   size_t size,
   int blockType,
   const char *filename,
   int linenumber
);
size
内存块的请求大小(以字节为单位)。

blockType
内存块的请求类型: _CLIENT_BLOCK或 _NORMAL_BLOCK。

filename
指向已请求分配操作的源文件名或NULL。

linenumber
请求分配操作所在的源文件中的行数或NULL。
文件名和linenumber参数只有在显式调用_malloc_dbg或定义_CRTDBG_MAP_ALLOC预处理器常量时才可用。

返回值

成功完成后,此函数将返回指向已分配的内存块用户部分的指针、 调用新处理程序函数,或返回NULL。 有关返回行为的完整说明,请参阅以下“备注”部分。 有关如何使用新处理程序函数的详细信息,请参阅 malloc 函数。
备注

_malloc_dbg是调试版malloc函数。 当_DEBUG未定义,则每次调用 _malloc_dbg缩减为调用malloc。 这两malloc并 _malloc_dbg分配基堆中的内存块,但 _malloc_dbg提供了几种调试功能: 用户两侧的缓冲区用于测试泄漏,用于跟踪特定分配类型的块类型参数的块部分和文件名/linenumber的信息来确定的来源分配请求。

_malloc_dbg分配稍多的空间比请求的内存块大小。 其他空间将由调试堆管理器用于链接调试内存块,以及提供具有调试标头信息的应用程序和覆盖缓冲区。 分配该块后,使用值 0xCD 填充该块的用户部分,使用值 0xFD 填充每个覆盖缓冲区。

_malloc_dbg设置errno到ENOMEM如果内存分配失败或 (包括之前提到过的开销) 所需的内存量超过 _HEAP_MAXREQ。 有关此代码及其他错误代码的信息,请参阅 errno、_doserrno、_sys_errlist 和 _sys_nerr。

有关如何在基堆的调试版本中分配、初始化和管理内存块的信息,请参阅 CRT Debug Heap Details。 有关分配块类型及其使用方式的信息,请参阅调试堆上的块类型。 有关在应用程序的调试版本中调用标准堆函数及其调试版本之间差异的信息,请参阅堆分配函数的调试版本。

_msize

返回在堆中分配的存储块的大小。
size_t _msize(
   void *memblock
);
memblock
指向内存块的指针。

返回值
_msize返回为无符号整数的大小 (以字节为单位)。

备注
_Msize函数返回的大小,以字节为单位,通过调用分配的内存块calloc, malloc,或者realloc。
当与 C 运行时库的调试版本链接应用程序 _msize解析为_msize_dbg。 有关在调试过程中如何托管堆的详细信息,请参阅 CRT 调试堆。
此函数验证其参数。 如果memblock为 null 指针 _msize调用无效参数处理程序,如中所述参数验证。 如果处理了错误,该函数将设置errno到EINVAL并返回-1。

LARGE_INTEGER

CWaitCursor

void CDisplayDlg::OnBnClickedOpendata()  
{  
    CWaitCursor waitCursor;  
    //....//耗时很长的代码  
    //if语句的最后会自动调用CWaitCursor的析构函数,替换回原来的光标    
} 

intptr_t是为了跨平台,其长度总是所在平台的位数,所以用来存放地址。

https://blog.csdn.net/macchan/article/details/38701811

mmioFOURCC

在mmiofourcc宏转换为四个字符的字符代码。

#define mmioFOURCC(ch0, ch1, ch2, ch3) \ 
    MAKEFOURCC(ch0, ch1, ch2, ch3); 

#define MAKEFOURCC(ch0, ch1, ch2, ch3)  \ 
    ((DWORD)(BYTE)(ch0) | ((DWORD)(BYTE)(ch1) << 8) |  \ 
    ((DWORD)(BYTE)(ch2) << 16) | ((DWORD)(BYTE)(ch3) << 24 )); 

FindFirstFile

void   FindFile(CString strPath,CString strFile,BOOL bPath,BOOL bRecursion,CStringArray &aFile)
{
	WIN32_FIND_DATA findData;
	HANDLE          hFind   = FindFirstFile(strPath + strFile ,&findData);	
	if(hFind != INVALID_HANDLE_VALUE)
	{
		if((findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == FILE_ATTRIBUTE_DIRECTORY && findData.cFileName[0] != '.')
		{
			if(bPath) aFile.Add(strPath + _L("\\") + findData.cFileName);
			if(bRecursion)  TP_FindFile(strPath + _L("\\") + findData.cFileName,_L("\\*.*"),bPath,bRecursion,aFile);
		}
		else if(!bPath && !((findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == FILE_ATTRIBUTE_DIRECTORY))
			aFile.Add(strPath + _L("\\") + findData.cFileName);

		while(FindNextFile(hFind,&findData))
		{
			if((findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == FILE_ATTRIBUTE_DIRECTORY && findData.cFileName[0] != '.')
			{
				if(bPath) aFile.Add(strPath + _L("\\") + findData.cFileName);
				if(bRecursion)  TP_FindFile(strPath + _L("\\") + findData.cFileName,_L("\\*.*"),bPath,bRecursion,aFile);
			}
			else if(!bPath && !((findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == FILE_ATTRIBUTE_DIRECTORY))
				aFile.Add(strPath + _L("\\") + findData.cFileName);
		}
		FindClose(hFind);
	}
}

CreateFile

SetFilePointer

WriteFile

DeleteFile

WideCharToMultiByte

//得到dll中对应的函数地址
void* CDynamicLibrary::GetFunAddress( const std::wstring& strFunName ) const
{
    //TODO: 封装
    int len= WideCharToMultiByte(CP_ACP,0,strFunName.c_str(),wcslen(strFunName.c_str()),NULL,0,NULL,NULL);  
    char* name =new char[len+1];  
    WideCharToMultiByte(CP_ACP,0,strFunName.c_str(),wcslen(strFunName.c_str()),name,len,NULL,NULL);  
    name[len]='\0'; 
    //
    void* pResult = NULL;
	if(m_hDynamicLib)
	{
        pResult = (void*)::GetProcAddress( (HMODULE)m_hDynamicLib,name);
	}

    delete[] name;

	return pResult;
}

MFC Cbutton 使用ModifyStyle修改文本多行风格   SetButtonStyle无效

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值