来自加载的dll资源的MFC查询读取顺序(RTL)?

时间:2013-05-09 16:19:54

标签: mfc right-to-left resource-dll

我们有一个旧的MFC应用程序,我们本地化为多种语言。我们有一个语言菜单,允许用户选择语言(需要重新启动应用程序)。当选择阿拉伯语等RTL语言时,主窗口框架和通过AfxMessageBox等调用在代码中创建的对话框保留在LTR中;即使在运行阿拉伯语窗口的系统上运行也是如此。我想根据加载的资源类型在我们创建的所有窗口上设置WS_EX_LAYOUTRTL位。有没有办法使用从AfxGetResourceHandle检索的句柄来查询资源是否是RTL?如果没有,还有另一种方法吗?

编辑:

所以只是为了澄清,我的问题是我的主窗口框架和所有动态对话框都保留在LTR布局中,即使加载的资源dll是RTL也是如此。我首先在我的app 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;
                    }
                }
            }
        }
    }
}

在我的资源文件中,about对话框是这样定义的,但是我似乎无法抓住代码中的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
}

感谢。

1 个答案:

答案 0 :(得分: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;
                    }
                }
            }
        }
    }
}