none
magnification.dll Memory leak RRS feed

  • 问题

  • hello all

      i want to capture the screen with magnification.dll and I found a memory leak  

      please help me,thanks.

      Every time I click the button, the memory will increase by 10M. (::OnBnClickedCaptureButton)

       i found that t when i call "set_window_source_func_" he memory will add.

       maybe the system will malloc buff to store one frame, how can i free them?

      my code:

          
    // kMagnifierWindowClass has to be "Magnifier" according to the Magnification
    // API. The other strings can be anything.
    static LPCTSTR kMagnifierHostClass   = L"ScreenCapturerWinMagnifierHost";
    static LPCTSTR kHostWindowName       = L"MagnifierHost";
    static LPCTSTR kMagnifierWindowClass = L"Magnifier";
    static LPCTSTR kMagnifierWindowName  = L"MagnifierWindow";
    
    typedef BOOL(WINAPI* MagImageScalingCallback)(HWND hwnd,
    	void* srcdata,
    	MAGIMAGEHEADER srcheader,
    	void* destdata,
    	MAGIMAGEHEADER destheader,
    	RECT unclipped,
    	RECT clipped,
    	HRGN dirty);
    
    typedef BOOL(WINAPI* MagInitializeFunc)(void);
    typedef BOOL(WINAPI* MagUninitializeFunc)(void);
    typedef BOOL(WINAPI* MagSetWindowSourceFunc)(HWND hwnd, RECT rect);
    typedef BOOL(WINAPI* MagSetWindowFilterListFunc)(HWND hwnd,
    	DWORD dwFilterMode,
    	int count,
    	HWND* pHWND);
    typedef BOOL(WINAPI* MagSetImageScalingCallbackFunc)(
    	HWND hwnd,
    	MagImageScalingCallback callback);
    
    HMODULE mag_lib_handle_ = NULL;
    MagInitializeFunc mag_initialize_func_ = nullptr;
    MagUninitializeFunc mag_uninitialize_func_ = nullptr;
    MagSetWindowSourceFunc set_window_source_func_ = nullptr;
    MagSetWindowFilterListFunc set_window_filter_list_func_ = nullptr;
    MagSetImageScalingCallbackFunc set_image_scaling_callback_func_ = nullptr;
    
    
    
    void Init()
    {
    	HMODULE hLib = LoadLibrary(L"dwmapi.dll");
    	typedef HRESULT(WINAPI* CxDwmIsCompositionEnabled)(_Out_ BOOL* pfEnabled);
    	CxDwmIsCompositionEnabled dce = reinterpret_cast<CxDwmIsCompositionEnabled>(
    		GetProcAddress(hLib, "DwmIsCompositionEnabled"));
    	BOOL result1;
    	if (HRESULT err = dce(&result1) != S_OK) {
    	}
    
    	mag_lib_handle_ = LoadLibrary(L"Magnification.dll");
    	if (!mag_lib_handle_)
    		return;
    
    	// Initialize Magnification API function pointers.
    	mag_initialize_func_ = reinterpret_cast<MagInitializeFunc>(
    		GetProcAddress(mag_lib_handle_, "MagInitialize"));
    	mag_uninitialize_func_ = reinterpret_cast<MagUninitializeFunc>(
    		GetProcAddress(mag_lib_handle_, "MagUninitialize"));
    	set_window_source_func_ = reinterpret_cast<MagSetWindowSourceFunc>(
    		GetProcAddress(mag_lib_handle_, "MagSetWindowSource"));
    	set_window_filter_list_func_ = reinterpret_cast<MagSetWindowFilterListFunc>(
    		GetProcAddress(mag_lib_handle_, "MagSetWindowFilterList"));
    	set_image_scaling_callback_func_ =
    		reinterpret_cast<MagSetImageScalingCallbackFunc>(
    			GetProcAddress(mag_lib_handle_, "MagSetImageScalingCallback"));
    
    	if (!mag_initialize_func_ || !mag_uninitialize_func_ ||
    		!set_window_source_func_ || !set_window_filter_list_func_ ||
    		!set_image_scaling_callback_func_) {
    		return;
    	}
    }
    
    void CMagCaptureDlg::OnBnClickedCaptureButton()
    {
    	//load magnification.dll and get the addr of func;
    	Init();
    
    	BOOL result = mag_initialize_func_();
    	if (!result) {return;}
    
    	// Create host dialog
    	hostDlg = new CHostDlg();
    	hostDlg->Create();
    	// Create magnification window
    	hwndMag = CreateWindow(WC_MAGNIFIER, TEXT("MagnifierWindow"),
    		WS_CHILD | WS_VISIBLE,
    		0, 0, m_ScreenX, m_ScreenY,
    		hostDlg->GetSafeHwnd(), NULL, hInstance, NULL);
    	if (hwndMag == NULL){return;}
    
    	// Set the callback function
    	if (!set_image_scaling_callback_func_(hwndMag, (MagImageScalingCallback)MagImageScaling)){
    		return;
    	}
    
    	// Filter the main window
    	if (!set_window_filter_list_func_(hwndMag, MW_FILTERMODE_EXCLUDE, 1, pFilterList)){
    		return;
    	}
    
    	// Get the screen rectangle
    	RECT sourceRect;
    	sourceRect.top = 0;
    	sourceRect.left = 0;
    	sourceRect.right = m_ScreenX;
    	sourceRect.bottom = m_ScreenY;
    
    	// Prepare the flag for the callback function
    	bCallbacked = FALSE;
    
    	// Set window source to capture entire the desktop
    	if (!set_window_source_func_(hwndMag, sourceRect)){
    		return;
    	}
    
    	RECT rcZero = { 0,0,0,0 };
    	// Set window source to capture entire the desktop
    	if (!set_window_source_func_(hwndMag, rcZero))
    	{
    		return;
    	}
    	// TODO: Add your message handler code here
    	// Free memory
    	if (hostDlg != NULL){
    		hostDlg->DestroyWindow();
    		delete hostDlg;
    	}
    	if (hwndMag != NULL){
    		::DestroyWindow(hwndMag);
    		hwndMag = NULL;
    	}
    
    	if (pData != NULL) {
    		delete pData;
    		pData = NULL;
    	}
    	// Uninitialize the magnification
    	bool bResult = mag_uninitialize_func_();
    
    	FreeLibrary(mag_lib_handle_);
    	mag_lib_handle_ = NULL;
    
    	return;
    }
    
    
    BOOL MagImageScaling(HWND hwnd, void *srcdata, MAGIMAGEHEADER srcheader,
    	void *destdata, MAGIMAGEHEADER destheader,
    	RECT unclipped, RECT clipped, HRGN dirty)
    {
    	dwThreadId1 = GetCurrentThreadId();
    
    	// Setup the bitmap info header
    	bmif.biSize = sizeof(BITMAPINFOHEADER);
    	bmif.biHeight = srcheader.height;
    	bmif.biWidth = srcheader.width;
    	bmif.biSizeImage = srcheader.cbSize;
    	bmif.biPlanes = 1;
    	bmif.biBitCount = (WORD)(bmif.biSizeImage / bmif.biHeight / bmif.biWidth * 8);
    	bmif.biCompression = BI_RGB;
    
    	// Prepare the buffer
    	if (pData != NULL)
    	{
    		delete pData;
    		pData = NULL;
    	}
    	pData = (BYTE*)malloc(bmif.biSizeImage);
    	memcpy(pData, srcdata, bmif.biSizeImage);
    
    	// The data bit is in top->bottom order, so we convert it to bottom->top order
    	LONG lineSize = bmif.biWidth * bmif.biBitCount / 8;
    	BYTE* pLineData = new BYTE[lineSize];
    	BYTE* pStart;
    	BYTE* pEnd;
    	LONG lineStart = 0;
    	LONG lineEnd = bmif.biHeight - 1;
    	while (lineStart < lineEnd)
    	{
    		// Get the address of the swap line
    		pStart = pData + (lineStart * lineSize);
    		pEnd = pData + (lineEnd * lineSize);
    		// Swap the top with the bottom
    		memcpy(pLineData, pStart, lineSize);
    		memcpy(pStart, pEnd, lineSize);
    		memcpy(pEnd, pLineData, lineSize);
    
    		// Adjust the line index
    		lineStart++;
    		lineEnd--;
    	}
    	delete[] pLineData;
    	// Set the flag to say that the callback function is finished
    	bCallbacked = TRUE;
    	return TRUE;
    }
    

    2019年1月27日 7:29

全部回复