0

我们有一个旧的 MFC 应用程序,已本地化为多种语言。我们有一个语言菜单,允许用户选择语言(需要重新启动应用程序)。When an RTL language such as Arabic is selected, the main window frame, and dialogs created in code via calls like AfxMessageBox, remain in LTR; 即使在以阿拉伯语运行 Windows 的系统上运行。我想根据加载的资源类型在我们创建的所有窗口上设置 WS_EX_LAYOUTRTL 位。有没有办法使用从 AfxGetResourceHandle 检索到的句柄来查询资源是否为 RTL?如果没有,还有其他方法可以做到这一点吗?

编辑:

所以为了澄清,我的问题是我的主窗口框架和所有动态对话框都保持在 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 );

编辑2:

仍在努力实现这一目标。我有以下我认为应该可以工作的代码,但事实并非如此。我知道我正在获取句柄的对话框将 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;
                    }
                }
            }
        }
    }
}

在我的资源文件中,关于对话框的定义是这样的,但我似乎无法掌握代码中的 EXSTYLE ......

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
}

谢谢。

4

1 回答 1

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;
                    }
                }
            }
        }
    }
}
于 2013-05-10T05:40:19.890 回答