2013-05-09 111 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; 
        } 
       } 
      } 
     } 
    } 
}