2013-05-09 78 views
0

我們有一箇舊的MFC應用程序,我們本地化爲多種語言。我們有一個語言菜單,允許用戶選擇語言(需要重新啓動應用程序)。當選擇諸如阿拉伯語之類的RTL語言時,主窗口框架和通過諸如AfxMessageBox之類的調用在代碼中創建的對話框保留在LTR中;即使在運行阿拉伯語窗口的系統上運行也是如此。我想根據加載的資源類型在我們創建的所有窗口上設置WS_EX_LAYOUTRTL位。有沒有辦法使用從AfxGetResourceHandle檢索的句柄來查詢資源是否爲RTL?如果沒有,是否有另一種方法來做到這一點?MFC查詢讀取順序(RTL)從加載的dll資源?

編輯:

所以只是爲了澄清,我的問題是,我的主窗口框架,和所有動態對話框保持在LTR佈局,即使加載資源DLL是RTL。基於存儲在註冊表中的三字母代碼,我通過從語言菜單下拉菜單中選擇一種語言來設置我的應用程序initinstance函數中的資源DLL第一件事。我所有的資源從DLL工作正常。我在主框架上只有一個問題,並且在發生錯誤時我們加載的通用對話框(如消息框)。或許此代碼段可以幫助解釋什麼,我在尋找:

BOOL CWinGFMainFrame::PreCreateWindow(CREATESTRUCT& cs) 
{ 
    HINSTANCE hInst = AfxGetResourceHandle(); 
    if(hInst) 
    { 
     //Add some logic here to determine if the loaded resource dll is RTL 
     cs.dwExStyle |= WS_EX_RTLREADING | WS_EX_LAYOUTRTL; 
    } 

    if(!CFrameWnd::PreCreateWindow(cs)) 
    { 
     return FALSE; 
    } 

    cs.style = WS_OVERLAPPED | WS_CAPTION | FWS_ADDTOTITLE 
      | WS_THICKFRAME | WS_SYSMENU | WS_MINIMIZEBOX 
      | WS_MAXIMIZEBOX | WS_MAXIMIZE; 

    return TRUE; 
} 

如果沒有這個方法,那麼有沒有我可以用它來確定基於像三個字母的國家的語言環境信息的閱讀順序的任何功能代碼或語言ID?在windows7的構建,我可以做到以下幾點,但我們需要支持Windows XP :(

int nResult = GetLocaleInfo (lcid, LOCALE_IREADINGLAYOUT, NULL, 0); 
TCHAR* szReadingLayout = new TCHAR[ nResult ]; 
nResult = GetLocaleInfo (lcid, LOCALE_IREADINGLAYOUT, szReadingLayout, nResult); 

EDIT2:。

仍然試圖讓這個打算,我有以下的代碼,我認爲應該工作,但它沒有,我知道我得到句柄的對話框將layoutrtl設置爲true,並且它有三個項目,當下面的代碼執行時,dwextendstyle是0,cdit也是0,但它應該是3.有沒有人看到我在這段代碼中做錯了什麼?我確實證實AfxGetResourceHandle正在返回一個句柄給我的阿拉伯語資源。

HINSTANCE hInst = AfxGetResourceHandle(); 
if(hInst) 
{ 
    //Make sure I'm looking at the right file. 
    char szPath[ MAX_PATH ]; 
    DWORD result = ::GetModuleFileName(hInst, szPath, MAX_PATH); 
    if(result) 
    { 
     ATLTRACE("Setting resource handle to %s\n", szPath); 
    } 

    // Locate the dialog box resource 
    HRSRC hRes = FindResource(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), RT_DIALOG); 
    if (hRes) 
    { 
     // Load the dialog box 
     HGLOBAL hResLoad = LoadResource(hInst, hRes); 
     if (hResLoad) 
     { 
      // Get a real pointer to the resource 
      LPVOID lpResLock = LockResource(hResLoad); 
      if (lpResLock) 
      { 
       // Cast the raw bits to something useful 
       LPDLGTEMPLATE pDlgTemplate = (LPDLGTEMPLATE)lpResLock; 
       if(pDlgTemplate) 
       { 
        if(pDlgTemplate->dwExtendedStyle & WS_EX_RTLREADING || 
         pDlgTemplate->dwExtendedStyle & WS_EX_LAYOUTRTL) 
        { 
         cs.dwExStyle |= WS_EX_RTLREADING | WS_EX_LAYOUTRTL; 
        } 
       } 
      } 
     } 
    } 
} 

在我的資源文件中的關於對話框的定義是這樣的,但我似乎無法得到我的手裏面的代碼的擴展風格...

100 DIALOGEX 0, 0, 257, 83, 0 
STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUPWINDOW | WS_DLGFRAME 
EXSTYLE WS_EX_LEFT | WS_EX_LTRREADING | WS_EX_RIGHTSCROLLBAR | WS_EX_LAYOUTRTL 
CAPTION "حول جهاز التدريب على طلب المساندة في إطلاق النيران" 
LANGUAGE LANG_ARABIC, SUBLANG_ARABICNEUTRAL 
FONT 8, "Tahoma" 
{ 
    ICON 128, -1, 7, 8, 20, 20 
    DEFPUSHBUTTON "موافق", 1, 178, 7, 50, 14, WS_GROUP, WS_EX_LEFT | WS_EX_LTRREADING | WS_EX_RIGHTSCROLLBAR | WS_EX_LAYOUTRTL 
    CTEXT "معلومات عن الإصدار", 1692, 44, 10, 130, 48, SS_NOPREFIX, WS_EX_LEFT | WS_EX_LTRREADING | WS_EX_RIGHTSCROLLBAR | WS_EX_LAYOUTRTL 
} 

感謝。

+0

對於AfxMessageBox,您需要MB_RTLREADING。通過查詢資源是否屬於RTL,你的意思是什麼? – FKDev 2013-05-09 16:56:07

+0

嗨FKDev,當應用程序啓動時,如果選擇英語以外的語言,它會加載已經本地化的資源DLL。我們支持的三種語言是阿拉伯語(巴林),達里語和普什圖語。這些是RTL語言。我正在尋找一種方法來發現加載的資源dll是否包含本地化爲RTL語言的資源。我要走這條路線,因爲如果我可以調用AfxGetResourceHandle並使用返回的句柄來查看其中的資源是否已針對RTL語言進行本地化,那將更容易。 – jdwieber 2013-05-09 17:43:15

+0

對話資源應該在RTL DLL中有WS_EX_LAYOUTRTL。 – FKDev 2013-05-09 19:00:08

回答

0

嗯,我不喜歡它,但我不得不求助於一些小玩意繼續前進。這是我的工作。我用英語和阿拉伯語進行測試。希望它能幫助別人。乾杯。

HINSTANCE hInst = AfxGetResourceHandle(); 
if(hInst) 
{ 
    // Locate the dialog box resource 
    HRSRC hRes = FindResource(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), RT_DIALOG); 
    if (hRes) 
    { 
     // Load the dialog box 
     HGLOBAL hResLoad = LoadResource(hInst, hRes); 
     if (hResLoad) 
     { 
      // Get a real pointer to the resource 
      LPVOID lpResLock = LockResource(hResLoad); 
      if (lpResLock) 
      { 
       // Do some raw bit manipulations 
       BYTE* pRaw = (BYTE*)lpResLock; 
       WORD signature = *(WORD*)(pRaw + sizeof(WORD)); 
       bool isDialogEx = (signature == 0xFFFF); 
       if(isDialogEx) 
       { 
        size_t offset = sizeof(WORD) + sizeof(WORD) + sizeof(DWORD); 
        DWORD exStyle = *(DWORD*)(pRaw + offset); 
        if(exStyle & WS_EX_RTLREADING || exStyle & WS_EX_LAYOUTRTL) 
        { 
         cs.dwExStyle |= WS_EX_RTLREADING | WS_EX_LAYOUTRTL; 
        } 
       } 
      } 
     } 
    } 
}