는 인스턴스 함수에 대한 올바른 주소를 얻을이 정말있는 유일한 방법입니다 :올바른 방법 과부하를 선택하는 더 좋은 방법은 무엇입니까?
이typedef CBitmap * (CDC::* SelectObjectBitmap)(CBitmap*);
SelectObjectBitmap pmf = (SelectObjectBitmap)&CDC::SelectObject;
첫째, 하나는 타입 정의를 만들 수 있으며, 다음 중 하나에 과부하가 올바른을 선택하도록 컴파일러에 강제로 그것을 사용하는 방법을 그 주소를 취할 때? 내 코드에서 자주 ScopeGuard를 사용
SelecdtObjectBitmap pmf = &CDC::SelectObject(CBitmap*);
:
이 같은 자연 및 독립적 인 아니 구문 없습니다. 한 가지 확실한 용도는 임시 CDC 개체가 지정된 DC로 먼저 선택된 다음 범위 종료에서 제거되어 예외적 인 상황에서도 코드가 누출되지 않도록하고 동시에 작성된 코드를 정리하는 것입니다 (바보 같은 다중 종료 경로 및 시도/catch 등을 사용하여 주어진 CDC에서 선택한 객체를 제거하려고 할 수 있습니다. 그것은 항상 난을하고자하는 나는 모든 오버로드 기능을 형식 정의를 할 필요가 지옥처럼 바보 같은 내게 쳤다
// get our client rect
CRect rcClient;
GetClientRect(rcClient);
// get the real DC we're drawing on
PAINTSTRUCT ps;
CDC * pDrawContext = BeginPaint(&ps);
// create a drawing buffer
CBitmap canvas;
canvas.CreateCompatibleBitmap(pDrawContext, rcClient.Width(), rcClient.Height());
CDC memdc;
memdc.CreateCompatibleDC(pDrawContext);
//*** HERE'S THE LINE THAT REALLY USES THE TYPEDEF WHICH i WISH TO ELIMINATE ***//
ScopeGuard guard_canvas = MakeObjGuard(memdc, (SelectObjectBitmap)&CDC::SelectObject, memdc.SelectObject(&canvas));
// copy the image to screen
pDrawContext->BitBlt(rcClient.left, rcClient.top, rcClient.Width(), rcClient.Height(), &memdc, rcClient.left, rcClient.top, SRCCOPY);
// display updated
EndPaint(&ps);
: 같은
그래서 나는 현재하도록 강요하고 무엇보다 완전한 예를 본다 의 주소.
그래서 ... 더 좋은 방법이 있습니까?!
편집 : 나를 위해 올바른 SelectObject 매크로 재정의 추론 MakeGuard에 대한 더 자연스러운 구문을 가지고 예 :
template <class GDIObj>
ObjScopeGuardImpl1<CDC, GDIObj*(CDC::*)(GDIObj*), GDIObj*> MakeSelectObjectGuard(CDC & dc, GDIObj * pGDIObj)
{
return ObjScopeGuardImpl1<CDC, GDIObj*(CDC::*)(GDIObj*), GDIObj*>::MakeObjGuard(dc, (GDIObj*(CDC::*)(GDIObj*))&CDC::SelectObject, dc.SelectObject(pGDIObj));
}
사람들이 제공 한 답변을 바탕으로, 나는 나의 기본적인 필요에 대한 해결책을 믿습니다 내 위의 코드 변경하는
:
ScopeGuard guard_canvas = MakeSelectObjectGuard(memdc, &canvas);
///////////////////////////////// ///////////////////////
같은 일의 비 MFC 버전 여기를 보일 수 있습니다 사람들을 위해 0:
//////////////////////////////////////////////////////////////////////////
//
// AutoSelectGDIObject
// selects a given HGDIOBJ into a given HDC,
// and automatically reverses the operation at scope exit
//
// AKA:
// "Tired of tripping over the same stupid code year after year"
//
// Example 1:
// CFont f;
// f.CreateIndirect(&lf);
// AutoSelectGDIObject select_font(*pDC, f);
//
// Example 2:
// HFONT hf = ::CreateFontIndirect(&lf);
// AutoSelectGDIObject select_font(hdc, hf);
//
// NOTE:
// Do NOT use this with an HREGION. Those don't need to be swapped with what's in the DC.
//////////////////////////////////////////////////////////////////////////
class AutoSelectGDIObject
{
public:
AutoSelectGDIObject(HDC hdc, HGDIOBJ gdiobj)
: m_hdc(hdc)
, m_gdiobj(gdiobj)
, m_oldobj(::SelectObject(m_hdc, gdiobj))
{
ASSERT(m_oldobj != m_gdiobj);
}
~AutoSelectGDIObject()
{
VERIFY(m_gdiobj == ::SelectObject(m_hdc, m_oldobj));
}
private:
const HDC m_hdc;
const HGDIOBJ m_gdiobj;
const HGDIOBJ m_oldobj;
};
//////////////////////// ///////////////////////
감사합니다. &이 (가) 댓글을 달았습니다. : D
당신은 할 수는 있지만, 확실히는 좋지 않을 것입니다 - 기본적으로 typedef 이름을 사용하는 typedef의 본문을 삽입하게 될 것입니다. – James
희망이 CBitmap이 아닙니다 : http://thedailywtf.com/Articles/The-cbitmap.aspx –