MFC DLL 리소스 동적 전환
이런 버그가 생겨서 한동안 손댈 수가 없었다.
오류 위치가 핵심 코드에서dlgcore.cpp.
BOOL AFXAPI _AfxCheckDialogTemplate(LPCTSTR lpszResource, BOOL bInvisibleChild)
{
ASSERT(lpszResource != NULL);
HINSTANCE hInst = AfxFindResourceHandle(lpszResource, RT_DIALOG);
HRSRC hResource = ::FindResource(hInst, lpszResource, RT_DIALOG);
if (hResource == NULL)
{
if (DWORD_PTR(lpszResource) > 0xffff)
TRACE(traceAppMsg, 0, _T("ERROR: Cannot find dialog template named '%s'.
"),
lpszResource);
else
TRACE(traceAppMsg, 0, "ERROR: Cannot find dialog template with IDD 0x%04X.
",
LOWORD((DWORD_PTR)lpszResource));
return FALSE;
}
......
return TRUE;
}
AfxFindResourceHandle에서 자원 파일을 찾을 때,exe에 있어야 할 자원을 찾았는데, 결과는 dll의 핸들을 되돌려줍니다.
해결 방법:
//
HINSTANCE hCurInstance = AfxGetResourceHandle();
//
AfxSetResourceHandle(theApp.m_hInstance);
Create(CTestDlg::IDD, GetDesktopWindow());
ShowWindow(SW_HIDE);
ShowWindow(SW_SHOWNOACTIVATE);
//
AfxSetResourceHandle(hCurInstance);
한 문장을 참조하여 마침내 그 속의 경위를 분명히 하였다.
기사 출처:http://blog.sina.com.cn/s/blog_62bb83b10100jbdj.html.
AFX_MANAGE_STATE(AfxGetStaticModuleState())
먼저 하나의 예를 보십시오.
1. MFC DLL에 동적으로 연결되는 규칙 DLL을 만들고 그 안에 대화 상자 자원이 포함되어 있습니다.대화상자 ID를 다음과 같이 지정합니다. #define IDDDLL_DIALOG 2000
2. 두 개의 대화상자 자원을 포함하는 대화상자 기반 mfc 프로그램을 만듭니다. IDDUI_DIALOG 및 IDDEXE_DIALOG.그리고 후자의 ID를 다음과 같이 지정합니다. #define IDDEXE_DIALOG 2000 중 전자는 이 프로그램의 사용자 인터페이스입니다. 위의 단추를 누르면 대화상자가 팝업됩니다.부분 코드는 다음과 같습니다://in DLL void CDLL::ShowDlg(void) {CDialog dlg(ID DLL DIALOG);//ID가 2000인 대화 상자 dlg.DoModal()를 엽니다.}//in EXE void CEXE::OnButtonClick() { ShowDlg(); } 3. 버튼을 클릭하면 원하는 DLL이 아닌 대화 상자 IDD 가 팝업됩니다.DLL_DIALOG 대신 응용 프로그램의 대화상자 IDDEXE_DIALOG.
설명:
1. 응용 프로그램 프로세스 자체와 호출된 모든 DLL 모듈은 전역적으로 유일한 HINSTANCE 핸들을 가지고 있으며 이것은 EXE 또는 DLL 모듈이 프로세스 가상 공간에서의 시작 주소를 대표한다.프로세스 자체의 모듈 핸들은 보통 0x400000이고 DLL 모듈의 기본 핸들은 0x100000000입니다. 프로그램이 여러 개의 DLL을 동시에 불러오면 각 DLL 모듈마다 다른 HINSTANCE가 있습니다. 응용 프로그램이 DLLL을 불러올 때 위치를 다시 정했습니다.
2. 공유 MFC DLL(또는 MFC 확장 DLL)의 규칙 DLL은 HINSTANCE 핸들 문제와 관련된다.
HINSTANCE 핸들은 리소스를 로드하는 데 특히 중요합니다.
.EXE 및 DLL 은 자체 리소스를 보유하고 있으며,
자원 ID가 중복될 수 있습니다.
, 애플리케이션이 규칙 DLL과 MFC DLL(또는 MFC 확장 DLL)을 공유하는 경우 항상
EXE를 사용하는 기본 리소스
.
3. 따라서 응용 프로그램은 자원 모듈의 전환을 통해 정확한 자원을 찾아야 한다.만약 응용 프로그램이 DLL에서 나온 자원을 필요로 한다면 자원 모듈 핸들을 DLL의 모듈 핸들로 지정해야 한다.EXE 파일에 포함된 리소스가 필요한 경우 리소스 모듈 핸들을 EXE의 모듈 핸들로 지정해야 합니다.
해결 방법: 1. DLL에서 향상된 기능:
방법
//in DLL void CDLL::ShowDlg(void) {AFX MANAGE STATE(AfxGet Static Module State(), CDialog dlg(ID DLL DIALOG),//ID가 2000인 대화 상자 dlg.DoModal()을 엽니다.
참고: AFXMANAGE_STATE(AfxGetStaticModuleState());인터페이스 함수로서의 첫 번째 문장이 틀림없다.스택에서 AFXMODULE_STATE 클래스의 인스턴스를 가리키며 pModuleState를 반환합니다. AFX_MODULE_STATE류는 그 구조 함수와 분석 함수를 이용하여 저장 모듈 상태 현장 및 현장 복구 작업을 한다.매크로는 pModuleState를 현재 유효한 모듈 상태로 설정하는 데 사용됩니다.이 매크로의 역할 영역을 떠날 때 (pModuleState가 가리키는 창고의 대상의 역할 영역을 떠날 때) 이전 모듈 상태는 클래스AFXMODULE_STATE의 분석 함수 복원.(즉, 자동 복구)
방법
//in DLL void CDLL::Show Dlg(void) {HINSTANCE save hInstance = AfxGetResourceHandle(), AfxSetResourceHandle(the App.m hInstance), CDialog dlg(ID DLL DIALOG),//ID가 2000인 대화상자 dlg. DoDoal() 열기, AfxSetourceHandle(save hInstance), }
참고: AfxGetResourceHandle: 현재 리소스 모듈 핸들 가져오기,AfxSetResourceHandle: 프로그램이 현재 사용할 자원 모듈 핸들을 설정합니다.방법1과 비교하면 방법2는 프로그램의 자원 모듈 핸들을 유연하게 설정할 수 있고 방법1은 DLL 인터페이스 함수가 종료될 때만 모듈 핸들을 복구할 수 있다.
2. 응용 프로그램에서 개선:
//in EXE void CEXE::OnButton Click() {HINSTANCE exe hInstance = GetModule Handle(NULL), HINSTANCE dll hInstance = GetModule Handle("Shareddll.dll"), AfxSetResource Handle(dll hInstance),//전환 상태 ShowDlg(), AfxSetource Handle(AfxSetource Handle Instance)
참고: 상태 전환을 사용하는 경우: DLL 내보내기 함수에 MFC 리소스, 클래스 또는 창을 만들어야 할 경우
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Ansible Module - Filestate: absent directory file ← default hard link touch absent : 디렉토리를 recursive하게 삭제한다. 심볼링 링크도 삭제한다. directory : 디렉토리가 ...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.