WinAPI - C++ - Một số vấn đề về kiểu dữ liệu chuỗi

char a = \17;
--> a là kiểu char, 1 byte, chứa giá trị hexa là 0x17
char a[] = "ABC";
--> a thực chất là con trỏ, trỏ đến mảng 4 ký tự, 3 ký tự ABC và ký tự kết thúc chuỗi, mỗi phần tử có kiểu char (1 byte)
char* a = "ABC";
--> a là con trỏ, trỏ đến mảng 4 ký tự, 3 ký tự ABC và ký tự kết thúc chuỗi, mỗi phần tử có kiểu char (1 byte)
wchar_t a[2]
--> a là mảng 2 phần tử, mỗi phần tử có kiểu wchar_t (2 bytes) - Wide character
LPCWSTR a
--> "Long Pointer to Constant Wide String"

1. Chuyển char (8 bits) sang LPCWSTR (pointer to array 16 bit per element, include Null terminal)
Xem ví dụ:
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    int wmId, wmEvent;
    PAINTSTRUCT ps;
    HDC hdc;
    RECT rect;
    char MyChar = 0;

    switch (message)
    {
    case WM_CHAR:
        MyChar = LOWORD(wParam);
        MessageBox(hWnd, (LPCWSTR)MyChar, (LPCWSTR)MyChar, MB_OK);
        break;
    case WM_DESTROY:
        PostQuitMessage(0);
        break;
    default:
        return DefWindowProc(hWnd, message, wParam, lParam);
    }
    return 0;
}
 
 --> Không được. Sửa lại:
 
 
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    int wmId, wmEvent;
    PAINTSTRUCT ps;
    HDC hdc;
    RECT rect;
    wchar_t myString[2];
    myString[1] = '\0'; // Ensure the second element is the null char

    switch (message)
    {
    case WM_CHAR:
        myString[0] = LOWORD(wParam); // Modify the first element only
        MessageBox(hWnd, myString, myString, MB_OK);
        break;
    case WM_DESTROY:
        PostQuitMessage(0);
        break;
    default:
        return DefWindowProc(hWnd, message, wParam, lParam);
    }
    return 0;
}
 
2. Chuyển từ LPARAM sang LPCWSTR:
Xem ví dụ:
 
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
 int wmId, wmEvent;
 static char buffer[] = "";

 switch (message)
 {
 case WM_COMMAND:
  wmId    = LOWORD(wParam);
  wmEvent = HIWORD(wParam);
  // Parse the menu selections:
  if (lParam==0)   // Menu selected
  {
   switch (wmId)
   {
   case IDM_GETTEXT:
    SendMessage(hWndEdit, WM_GETTEXT, 1024, (LPARAM)buffer);
    MessageBox(hWnd, (LPCWSTR)buffer, L"Caption", MB_OK);
    break;
   default:
    return DefWindowProc(hWnd, message, wParam, lParam);
   }
  }
  break;
 case WM_DESTROY:
  PostQuitMessage(0);
  break;
 default:
  return DefWindowProc(hWnd, message, wParam, lParam);
 }
 return 0;
}  

--> Dùng char[] làm trung gian, chuyển ouput kiểu LPARAM sang input LPCWSTR

3. Chuyển từ wParam sang LPCWSTR

wchar_t buffer[256];
wsprintfW(buffer, L"%p", wParam);
SetDlgItemText(hWnd, IDC_HANDLE, buffer);

--> Dùng wsprintf với "%p", kết hợp với trung gian là 1 mảng wchar_t

4. Chuyển UTF_8 sang UTF_16 dùng MultiByteToWideChar

 Hãy xem ví dụ sau:

            szFileName = L"abc.txt";
            hFile = CreateFile(szFileName, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, 0, OPEN_EXISTING, FILE_ATTRIBUTE_ARCHIVE, NULL);
            hMapFile = CreateFileMapping(hFile, NULL, PAGE_READONLY, 0, 0, NULL);

            pMemory = MapViewOfFile(hMapFile, FILE_MAP_READ, 0,0,0);

            int size_needed = MultiByteToWideChar(CP_UTF8, 0, (LPCCH)pMemory, -1, NULL, 0);
            wchar_t *buffer = new wchar_t[size_needed];
            MultiByteToWideChar(CP_UTF8, 0, (LPCCH)pMemory, -1, buffer, size_needed);

            FileSize = GetFileSize(hFile, NULL);
            SendMessage(hWndEdit, WM_SETTEXT, 0, (LPARAM)buffer);
            delete[] buffer;
            UnmapViewOfFile(pMemory);
            CloseHandle(hMapFile);
            CloseHandle(hFile);

Phần màu đỏ chuyển từ pMemory (LPVOID) sang wchar_t (LPCWSTR) ở buffer.

5.  Chuyển wchar_t sang int:

Cái này phải quất 1 hàm tự tạo để chuyển.
Giả sử ta có mảng wchar_t a, muốn chuyển sang biến int i (ví dụ "54" thành 54)

int miniPow(int a, int b)    // tính lũy thừa cơ bản (số nhỏ)
{
    int r = 1;
    for (int i = 0; i < b; i++)
    {
        r *= a;
    }
    return r;
}
int WideToInt(wchar_t a[])
{
    int i = 0;
    int len = wcslen(a);
    int bac = 0;
    int RawNumber = 0;
    int Number = 0;
   
    for (int k = 0; k < len; k++)
    {
        bac = len - 1 - k;
        RawNumber = (int)a[k];
        Number = RawNumber - 48;
        i += miniPow(10, bac) * Number;
    }
    return i;
}

Nhận xét

  1. Anh ơi, sao em định nghĩa :
    char a =\17;
    trong C++, VS 2012 thì báo lỗi ?

    Trả lờiXóa

Đăng nhận xét