Problem with PathMatchSpec() for Korean language

266 Views Asked by At

The functions PathMatchSpec() and PathMatchSpecEx() return incorrect results for the Korean language.

In the test program below, the name is "수납파일" and the mask is "수납*".

If the Windows language is e.g. English or German - it works fine.

If the Windows language is Korean, both functions return incorrect results.

How should I use the functions to make them work properly in all languages?

I don't know the Korean language. Tested on Windows 10 and 11 with Delphi 10.4.2.

C++ console:

#include <iostream>
#include <shlwapi.h>
#pragma comment(lib, "Shlwapi.lib")
int main()
{
    if (PathMatchSpec(L"수납파일", L"수납*"))
       std::cout << "PathMatchSpec success!\n";
    else
        std::cout << "PathMatchSpec failed!\n";

    if (PathMatchSpecEx(L"수납파일", L"수납*", PMSF_NORMAL)==S_OK)
        std::cout << "PathMatchSpecEx success!\n";
    else
        std::cout << "PathMatchSpecEx failed!\n";
}

Test program:

unit Unit1;

interface

uses
  Winapi.Windows, Winapi.Messages,Winapi.ShLwApi,
  System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls;

type
  TForm1 = class(TForm)
    Edit1: TEdit;
    Label1: TLabel;
    Label2: TLabel;
    Edit2: TEdit;
    Button1: TButton;
    Label3: TLabel;
    Button2: TButton;
    Label4: TLabel;
    procedure FormCreate(Sender: TObject);
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;    

  function PathMatchSpecEx(pszFile, pszSpec: LPCWSTR; dwFlags: DWORD ): HRESULT; stdcall;
  {$EXTERNALSYM PathMatchSpecEx}
var
  Form1: TForm1;

implementation

{$R *.dfm}


function PathMatchSpecEx; external 'shlwapi.dll' name 'PathMatchSpecExW';    


procedure TForm1.FormCreate(Sender: TObject);
var fileName, fileMask: string;
begin
  fileName := '수납파일';
  fileMask:= '수납*';

  Edit1.Text := fileName;
  Edit2.Text := fileMask;   

end;   


procedure TForm1.Button1Click(Sender: TObject);
var fileName, fileMask: string;
begin
  fileName := Edit1.Text;
  fileMask := Edit2.Text;

  if PathMatchSpecEx(PChar(fileName), PChar(fileMask),0)=S_OK then
     Label3.Caption := 'Success!'
  else
     Label3.Caption := 'PathMatchSpecEx failed!';
end;

procedure TForm1.Button2Click(Sender: TObject);
var fileName, fileMask: string;
begin
  fileName := Edit1.Text;
  fileMask := Edit2.Text;

  if PathMatchSpec(PChar(fileName), PChar(fileMask)) then
     Label4.Caption := 'Success!'
  else
     Label4.Caption := 'PathMatchSpec failed!';
end;

end.
1

There are 1 best solutions below

2
YangXiaoPo-MSFT On

The code page of the source file makes a difference as you said in comments. The following code explains what happened.

#include<windows.h>
#include <iostream>
#include <wchar.h>
#include <shlwapi.h>
#pragma comment(lib, "Shlwapi.lib")

PCHAR convert(PTCHAR p)
{
    int size = WideCharToMultiByte(50225, 0, p, -1, NULL, 0, NULL, NULL);
    PCHAR c = (PCHAR)malloc(size);
    int error = WideCharToMultiByte(50225, 0, p, -1, c, size, NULL, NULL);
    if (error == 0)
    {
        DWORD d = GetLastError();
    }
    return c;
}

int main()
{
    TCHAR a[] = L"수납파일";
    TCHAR b[] = L"수납*";

    PCHAR c = convert(a);
    PCHAR d = convert(b);
    //d[9] = '\x2a';
    //d[10] = '\x0';
    if (PathMatchSpec(a, b))
        std::cout << "PathMatchSpec success!\n";
    else
        std::cout << "PathMatchSpec failed!\n";

    if (PathMatchSpecEx(a, b, PMSF_NORMAL) == S_OK)
        std::cout << "PathMatchSpecEx success!\n";
    else
        std::cout << "PathMatchSpecEx failed!\n";

    if (PathMatchSpecA(c, d))
        std::cout << "PathMatchSpec success!\n";
    else
        std::cout << "PathMatchSpec failed!\n";

    if (PathMatchSpecExA(c, d, PMSF_NORMAL) == S_OK)
        std::cout << "PathMatchSpecEx success!\n";
    else
        std::cout << "PathMatchSpecEx failed!\n";
}


Save the source file in code page 50225.
overall overall
aa
bb


Save the source file in Unicode code page 65001.
overalloverall
aa
bb
cc
dd\