Codeblocks Win32 对话框项目中的 Unicode 问题(已解决)

问题描述 投票:0回答:1

我正在尝试通过 CodeBlocks 制作 Unicode 程序(波斯语),但似乎这并不容易!

这是我迄今为止尝试过的:

首先我通过Resedit程序创建Win32 GUI对话框项目和设计资源。 我在Resedit和CodeBlocks(设置->编辑器>编码设置)中将编码设置为UTF-8,并将字体设置为Tahoma(此字体包括波斯字符)。 在 Resedit Preview 和 CodeBlocks 编辑器中(当我打开资源文件时),所有内容都显示正确,但是当我编译项目时,字符显示不正确。

1 重新编辑预览

2 已编译

#include <windows.h>
#include <commctrl.h>
#include <richedit.h>
#include "resource.h"




//
// Dialog resources
//
LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL
DLG_MAIN DIALOG 0, 0, 186, 95
STYLE DS_3DLOOK | DS_CENTER | DS_MODALFRAME | DS_SETFONT | WS_CAPTION | WS_VISIBLE | WS_POPUP | WS_SYSMENU
EXSTYLE WS_EX_LAYOUTRTL
CAPTION "ثبت"
FONT 8, "Tahoma"
{
    PUSHBUTTON      "تایید", 0, 75, 40, 50, 14, 0, WS_EX_LEFT
    LTEXT           "متن:", 0, 26, 20, 14, 9, SS_LEFT, WS_EX_LEFT
    EDITTEXT        0, 50, 20, 100, 14, ES_AUTOHSCROLL, WS_EX_LEFT
}



//
// Manifest resources
//
LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL
1                  RT_MANIFEST    ".\\manifest.xml"

资源文件代码

#include <windows.h>
#include <commctrl.h>
#include <stdio.h>
#include "resource.h"

HINSTANCE hInst;

BOOL CALLBACK DlgMain(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    switch(uMsg)
    {
    case WM_INITDIALOG:
    {
    }
    return TRUE;

    case WM_CLOSE:
    {
        EndDialog(hwndDlg, 0);
    }
    return TRUE;

    case WM_COMMAND:
    {
        switch(LOWORD(wParam))
        {
        }
    }
    return TRUE;
    }
    return FALSE;
}


int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)
{
    hInst=hInstance;
    InitCommonControls();
    return DialogBox(hInst, MAKEINTRESOURCE(DLG_MAIN), NULL, (DLGPROC)DlgMain);
}

Main.CPP(在代码块中)

第二我在CodeBlocks中创建Win32Gui框架项目并再次尝试构建这个窗口,但这次我在谷歌搜索后更改了一些内容。

 #if defined(UNICODE) && !defined(_UNICODE)
#define _UNICODE
#elif defined(_UNICODE) && !defined(UNICODE)
    #define UNICODE
#endif
    
#include <tchar.h>
#include <windows.h>
#include "commctrl.h"


LRESULT CALLBACK WindowProcedure (HWND, UINT, WPARAM, LPARAM);


wchar_t szClassName[ ] = L"CodeBlocksWindowsApp";

int WINAPI WinMain (HINSTANCE hThisInstance,
                     HINSTANCE hPrevInstance,
                     LPSTR lpszArgument,
                     int nCmdShow)
{
    HWND hwnd;               
    MSG messages;           
    WNDCLASSEXW wincl;        

    /* The Window structure */
    wincl.hInstance = hThisInstance;
    wincl.lpszClassName = szClassName;
    wincl.lpfnWndProc = WindowProcedure;      
    wincl.style = CS_DBLCLKS;                 
    wincl.cbSize = sizeof (WNDCLASSEX);


    wincl.hIcon = LoadIcon (NULL, IDI_APPLICATION);
    wincl.hIconSm = LoadIcon (NULL, IDI_APPLICATION);
    wincl.hCursor = LoadCursor (NULL, IDC_ARROW);
    wincl.lpszMenuName = NULL;                 
    wincl.cbClsExtra = 0;                      
    wincl.cbWndExtra = 0;                  

    wincl.hbrBackground = (HBRUSH)(COLOR_3DFACE + 1);

    
    if (!RegisterClassExW (&wincl))
        return 0;


    hwnd = CreateWindowExW (
           WS_EX_LAYOUTRTL,                  
           szClassName,         
           L"ثبت",       
           WS_OVERLAPPEDWINDOW, 
           CW_USEDEFAULT,       
           CW_USEDEFAULT,     
           285,                 
           183,                 
           HWND_DESKTOP,       
           NULL,               
           hThisInstance,     
           NULL                
           );

    
    ShowWindow (hwnd, nCmdShow);

 
    while (GetMessage (&messages, NULL, 0, 0))
    {
      
        TranslateMessage(&messages);

        DispatchMessage(&messages);


    }


    return messages.wParam;
}




LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    switch (message)                  
    {
    case WM_CREATE:
        {


            HFONT hfont = CreateFont(-11, 0, 0, 0, 0, FALSE, FALSE, FALSE, 1, 0, 0, 0, 0, ("Tahoma"));
            HWND btnhwnd = CreateWindowW(WC_BUTTONW, L"تایید", WS_VISIBLE | WS_CHILD | WS_TABSTOP, 111, 65, 75, 23, hwnd,NULL, NULL, 0);
            SendMessageW(btnhwnd, WM_SETFONT, (WPARAM)hfont, TRUE);
            HWND statichwnd = CreateWindowW( WC_STATICW, L"متن:", WS_VISIBLE | WS_CHILD | WS_GROUP | SS_LEFT, 38, 33, 21, 15, hwnd, NULL, NULL, 0);
            SendMessageW(statichwnd, WM_SETFONT, (WPARAM)hfont, TRUE);
            HWND edithwnd = CreateWindowW(WC_EDITW, L"", WS_VISIBLE | WS_CHILD | WS_TABSTOP | WS_BORDER | ES_AUTOHSCROLL, 74, 33, 150, 23, hwnd, NULL, NULL, 0);
            SendMessageW(edithwnd, WM_SETFONT, (WPARAM)hfont, TRUE);
        }
break;
        case WM_DESTROY:
            PostQuitMessage (0);      
            break;
        default:                     
            return DefWindowProcW (hwnd, message, wParam, lParam);
    }

    return 0;
}

为了正确显示 unicode 字符,我更改了这些项目:

DefWindowProc to DefWindowProcW
SendMessage to SendMessageW
CreateWindow to CreateWindowExW
Char szClassName[ ] to  wchar_t szClassName[ ]
WNDCLASS wincl to  WNDCLASSEXW wincl
!RegisterClass (&wincl) to !RegisterClassExW (&wincl)

此函数/命令支持 unicode,但正如您所见,这些命令在 Win32 Dialog 项目中不存在!

搜索后我发现对话框项目中的这一行似乎导致 Unicode 无法正确显示:

  int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE 
                      hPrevInstance, LPSTR lpCmdLine, int nShowCmd)

return DialogBox(hInst, MAKEINTRESOURCE(DLG_MAIN), NULL

我尝试在 Visual Studio 中制作类似的项目,看看 Visual Studio 做了什么,我是否可以在代码块中做同样的事情。

Visual Studio win32对话框项目由资源文件和main.cpp文件组成,这些是代码:

#include <Windows.h>
#include <CommCtrl.h>
#include <tchar.h>
#include "resource.h"

#pragma comment(linker, \
  "\"/manifestdependency:type='Win32' "\
  "name='Microsoft.Windows.Common-Controls' "\
  "version='6.0.0.0' "\
  "processorArchitecture='*' "\
  "publicKeyToken='6595b64144ccf1df' "\
  "language='*'\"")

#pragma comment(lib, "ComCtl32.lib")

INT_PTR CALLBACK DialogProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
  switch(uMsg)
  {
  case WM_COMMAND:
    switch(LOWORD(wParam))
    {
    case IDCANCEL:
      SendMessage(hDlg, WM_CLOSE, 0, 0);
      return TRUE;
    }
    break;

  case WM_CLOSE:
    if(MessageBox(hDlg, TEXT("Close the program?"), TEXT("Close"),
      MB_ICONQUESTION | MB_YESNO) == IDYES)
    {
      DestroyWindow(hDlg);
    }
    return TRUE;

  case WM_DESTROY:
    PostQuitMessage(0);
    return TRUE;
  }

  return FALSE;
}

int WINAPI _tWinMain(HINSTANCE hInst, HINSTANCE h0, LPTSTR lpCmdLine, int nCmdShow)
{
  HWND hDlg;
  MSG msg;
  BOOL ret;

  InitCommonControls();
  hDlg = CreateDialogParam(hInst, MAKEINTRESOURCE(IDD_DIALOG1), 0, DialogProc, 0);
  ShowWindow(hDlg, nCmdShow);

  while((ret = GetMessage(&msg, 0, 0, 0)) != 0) {
    if(ret == -1)
      return -1;

    if(!IsDialogMessage(hDlg, &msg)) {
      TranslateMessage(&msg);
      DispatchMessage(&msg);
    }
  }

  return 0;
}

主要.cpp

    // Microsoft Visual C++ generated resource script.
//
#include "resource.h"

#define APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 2 resource.
//
#include "afxres.h"

/////////////////////////////////////////////////////////////////////////////
#undef APSTUDIO_READONLY_SYMBOLS

/////////////////////////////////////////////////////////////////////////////
// Persian (fa-IR) resources

#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_FAR)
LANGUAGE LANG_PERSIAN, SUBLANG_DEFAULT

#ifdef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// TEXTINCLUDE
//

1 TEXTINCLUDE 
BEGIN
    "resource.h\0"
END

2 TEXTINCLUDE 
BEGIN
    "#include ""afxres.h""\r\n"
    "\0"
END

3 TEXTINCLUDE 
BEGIN
    "\r\n"
    "\0"
END

#endif    // APSTUDIO_INVOKED


/////////////////////////////////////////////////////////////////////////////
//
// Dialog
//

IDD_DIALOG1 DIALOGEX 0, 0, 223, 83
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU
EXSTYLE WS_EX_LAYOUTRTL
CAPTION "ثبت"
FONT 8, "MS Shell Dlg", 400, 0, 0x1
BEGIN
    DEFPUSHBUTTON   "تایید",IDOK,85,49,50,14
    EDITTEXT        IDC_EDIT1,61,28,98,14,ES_AUTOHSCROLL
    LTEXT           "نام:",IDC_STATIC,46,31,12,8
END


/////////////////////////////////////////////////////////////////////////////
//
// DESIGNINFO
//

#ifdef APSTUDIO_INVOKED
GUIDELINES DESIGNINFO
BEGIN
    IDD_DIALOG1, DIALOG
    BEGIN
        LEFTMARGIN, 7
        RIGHTMARGIN, 216
        TOPMARGIN, 7
        BOTTOMMARGIN, 76
    END
END
#endif    // APSTUDIO_INVOKED

#endif    // Persian (fa-IR) resources
/////////////////////////////////////////////////////////////////////////////



#ifndef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 3 resource.
//


/////////////////////////////////////////////////////////////////////////////
#endif    // not APSTUDIO_INVOKED

资源.rc

如您所见,Visual Studio 使用以下 winmain 函数定义:

int WINAPI _tWinMain(HINSTANCE hInst, HINSTANCE h0, LPTSTR lpCmdLine, int nCmdShow)

我尝试在代码块中使用 Visual Studio 源代码(复制粘贴源代码)来解决问题,但代码块无法执行它并导致以下错误:

undefined reference to '_WinMain@16

我什至尝试解决这个错误,但没有成功并且代码块崩溃了! 当我将 unicode 设置为 utf-16 时,代码块中也出现了惊人的错误(debug show #ifdef 命令有问题!)

Visual Studio 可以正确显示 Unicode 字符,但代码块却不能。 您对我的问题有何看法和建议? (感谢并抱歉我的长问题)

winapi unicode codeblocks
1个回答
1
投票

经过大量搜索和尝试/错误终于解决了问题。

我做了什么:

--将resource.rc文件保存为UTF-8编码

--将“#pragma code_page(65001)”添加到resource.rc文件的第一行(不带双引号)

--使用DialogBoxW代替DialogBox命令

--使用 MAKEINTRESOURCEW 而不是 MAKEINTRESOURCE

最后,所有 Unicode 文本都能正确显示。

© www.soinside.com 2019 - 2024. All rights reserved.