RSDN::CHandle
От: Аноним  
Дата: 27.10.02 07:50
Оценка: 180 (2)
Статья:
RSDN::CHandle
Автор(ы): Павел Блудов, Владислав Чистяков
Пример класса-обертки для работы с хендлами.


Авторы:
VladD2
Блудов Павел

Аннотация:
Пример класса-обертки для работы с хендлами.
CHandle - duplicate
От: RS Земля ICQ: 148844272
Дата: 05.11.02 10:38
Оценка:
То же самое я делал без возможности duplicate (чисто субъективно, не доверяю я ей). По этой причине конструктор копирования и оператор присваивания (другого CHandle) я бы сделал private (да в своей версии так и сделал).
re
От: Евгений Коробко  
Дата: 28.10.02 09:22
Оценка:
А ещё было бы здорово для всех структур из windows API (Например, WNDCLASSEX) сделать конструкторы по умолчанию, которые бы заполняли структуру default-значениями. Впрочем, возникает вопрос: насколько актуальны сейчас обертки над Win API элементами в плане неизбежного перехода на .NET?
Евгений Коробко
Сильная вещь !
От: Аноним  
Дата: 28.10.02 07:50
Оценка:
Вот бы такое для Mutex,Event,Semaphore и тд... :)
Re: Сильная вещь !
От: Блудов Павел Россия  
Дата: 28.10.02 08:49
Оценка:
А это Вам задание на дом :)
Написать три класса, наследованных от CHandle и реализующие еще по паре методов, типа:

class CEvent : public CHandle
{
public:
BOOL SetEvent() const
{
return ::SetEvent(*this);
}
// ...
};

и т.д.

Павел.
Re: RSDN::CHandle
От: MShura  
Дата: 16.01.04 21:41
Оценка:
Здравствуйте, Павел Блудов, Владислав Чистяков, Вы писали:

ПБВ>Статья:



ПБВ>Авторы:

ПБВ> VladD2
ПБВ> Блудов Павел

ПБВ>Аннотация:

ПБВ>Пример класса-обертки для работы с хендлами.

Дж.Рихтер ( а заодно и я с ним ) пользуется такой оберткой.


/******************************************************************************
Module:  EnsureCleanup.h
Notices: Copyright (c) 2000 Jeffrey Richter
Purpose: These classes ensure object cleanup when an object goes out of scope.
         See Appendix B.
******************************************************************************/


#pragma once   // Include this header file once per compilation unit


///////////////////////////////////////////////////////////////////////////////


#include "..\CmnHdr.h"                    // See Appendix A.


///////////////////////////////////////////////////////////////////////////////


// Data type representing the address of the object's cleanup function.
// I used UINT_PTR so that this class works properly in 64-bit Windows.
typedef VOID (WINAPI* PFNENSURECLEANUP)(UINT_PTR);


///////////////////////////////////////////////////////////////////////////////


// Each template instantiation requires a data type, address of cleanup 
// function, and a value that indicates an invalid value.
template<class TYPE, PFNENSURECLEANUP pfn, UINT_PTR tInvalid = NULL> 
class CEnsureCleanup {
public:
   // Default constructor assumes an invalid value (nothing to cleanup)
   CEnsureCleanup() { m_t = tInvalid; }

   // This constructor sets the value to the specified value
   CEnsureCleanup(TYPE t) : m_t((UINT_PTR) t) { }

   // The destructor performs the cleanup.
   ~CEnsureCleanup() { Cleanup(); }

   // Helper methods to tell if the value represents a valid object or not..
   BOOL IsValid() { return(m_t != tInvalid); }
   BOOL IsInvalid() { return(!IsValid()); }

   // Re-assigning the object forces the current object to be cleaned-up.
   TYPE operator=(TYPE t) { 
      Cleanup(); 
      m_t = (UINT_PTR) t;
      return(*this);  
   }

   // Returns the value (supports both 32-bit and 64-bit Windows).
   operator TYPE() { 
      // If TYPE is a 32-bit value, cast m_t to 32-bit TYPE
      // If TYPE is a 64-bit value, case m_t to 64-bit TYPE
      return((sizeof(TYPE) == 4) ? (TYPE) PtrToUint(m_t) : (TYPE) m_t); 
   }

   // Cleanup the object if the value represents a valid object
   void Cleanup() { 
      if (IsValid()) {
         // In 64-bit Windows, all parameters are 64-bits, 
         // so no casting is required
         pfn(m_t);         // Close the object.
         m_t = tInvalid;   // We no longer represent a valid object.
      }
   }
   
private:
   UINT_PTR m_t;           // The member representing the object
};


///////////////////////////////////////////////////////////////////////////////


// Macros to make it easier to declare instances of the template 
// class for specific data types.

#define MakeCleanupClass(className, tData, pfnCleanup) \
   typedef CEnsureCleanup<tData, (PFNENSURECLEANUP) pfnCleanup> className;

#define MakeCleanupClassX(className, tData, pfnCleanup, tInvalid) \
   typedef CEnsureCleanup<tData, (PFNENSURECLEANUP) pfnCleanup, \
   (INT_PTR) tInvalid> className;


///////////////////////////////////////////////////////////////////////////////


// Instances of the template C++ class for common data types.
MakeCleanupClass(CEnsureCloseHandle,        HANDLE,    CloseHandle);
MakeCleanupClassX(CEnsureCloseFile,         HANDLE,    CloseHandle, 
   INVALID_HANDLE_VALUE);
MakeCleanupClass(CEnsureLocalFree,          HLOCAL,    LocalFree);
MakeCleanupClass(CEnsureGlobalFree,         HGLOBAL,   GlobalFree);
MakeCleanupClass(CEnsureRegCloseKey,        HKEY,      RegCloseKey);
MakeCleanupClass(CEnsureCloseServiceHandle, SC_HANDLE, CloseServiceHandle);
MakeCleanupClass(CEnsureCloseWindowStation, HWINSTA,   CloseWindowStation);
MakeCleanupClass(CEnsureCloseDesktop,       HDESK,     CloseDesktop);
MakeCleanupClass(CEnsureUnmapViewOfFile,    PVOID,     UnmapViewOfFile);
MakeCleanupClass(CEnsureFreeLibrary,        HMODULE,   FreeLibrary);


///////////////////////////////////////////////////////////////////////////////


// Special class for releasing a reserved region.
// Special class is required because VirtualFree requires 3 parameters
class CEnsureReleaseRegion {
public:
   CEnsureReleaseRegion(PVOID pv = NULL) : m_pv(pv) { }
   ~CEnsureReleaseRegion() { Cleanup(); }

   PVOID operator=(PVOID pv) { 
      Cleanup(); 
      m_pv = pv; 
      return(m_pv); 
   }
   operator PVOID() { return(m_pv); }
   void Cleanup() { 
      if (m_pv != NULL) { 
         VirtualFree(m_pv, 0, MEM_RELEASE); 
         m_pv = NULL; 
      } 
   }
   
private:
   PVOID m_pv;
};


///////////////////////////////////////////////////////////////////////////////


// Special class for freeing a block from a heap
// Special class is required because HeapFree requires 3 parameters
class CEnsureHeapFree {
public:
   CEnsureHeapFree(PVOID pv = NULL, HANDLE hHeap = GetProcessHeap()) 
      : m_pv(pv), m_hHeap(hHeap) { }
   ~CEnsureHeapFree() { Cleanup(); }

   PVOID operator=(PVOID pv) { 
      Cleanup(); 
      m_pv = pv; 
      return(m_pv); 
   }
   operator PVOID() { return(m_pv); }
   void Cleanup() { 
      if (m_pv != NULL) { 
         HeapFree(m_hHeap, 0, m_pv); 
         m_pv = NULL; 
      } 
   }
   
private:
   HANDLE m_hHeap;
   PVOID m_pv;
};


///////////////////////////////// End of File /////////////////////////////////
Re[2]: RSDN::CHandle
От: mikа Stock#
Дата: 17.01.04 13:43
Оценка: +2
Здравствуйте, MShura, Вы писали:

MS>Дж.Рихтер ( а заодно и я с ним ) пользуется такой оберткой.


Рихтер уже другим пользуется
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.