Trang 1 trên tổng số 2 12 Cuối cùngCuối cùng
Từ 1 tới 10 trên tổng số 12 kết quả

Đề tài: Lỗi khi chuyển CxImage sang mã Unicode

  1. #1
    Ngày gia nhập
    06 2007
    Bài viết
    18

    Mặc định Lỗi khi chuyển CxImage sang mã Unicode

    em đang chuyển cái cximage từ ANSI sang UNICODE để tích hợp tiếng Việt vào thì nó báo một số lỗi. Trong đó có một lỗi như sau:

    Lỗi thứ nhất:

    C2664: 'sprintf' : cannot convert parameter 1 from 'WCHAR [32]' to 'char *'

    từ dòng lệnh này
    Code:
    sprintf(m_text.lfont.lfFaceName, GetProfileString( _T("TextTool"), _T("lfFaceName"), _T("Arial")) );
    em đã thử sử dụng cái _T() cho m_text.lfont.lfFaceName nhưng nó vẫn báo lỗi. đã thử đặt (char *)
    Code:
    sprintf((char *)m_text.lfont.lfFaceName, GetProfileString( _T("TextTool"), _T("lfFaceName"), _T("Arial")) );
    nhưng vẫn không khắc phục được lỗi.

    Lỗi thứ hai:

    error C2665: 'AfxMessageBox' : none of the 2 overloads could convert all the argument types
    khi sử dụng câu lệnh sau:

    Code:
    if (!newImage->LoadResource(FindResource(NULL,MAKEINTRESOURCE(IDB_BITMAP1),RT_BITMAP),CXIMAGE_FORMAT_BMP)){
    		AfxMessageBox(newImage->GetLastError());
    bác nào đã gặp lỗi này bày em cách khắc phục với. Đang tập tễnh bước vào VC.NET lại gặp lỗi xương quá.
    Đã được chỉnh sửa lần cuối bởi choa : 28-12-2007 lúc 02:30 PM. Lý do: Thêm thông tin
    Vouloir C'est pouvoir

  2. #2
    Ngày gia nhập
    08 2006
    Nơi ở
    TpHCM
    Bài viết
    202

    lỗi 1:
    bạn đã dùng macro _T() thì dùng
    macro _stprintf() thay cho sprintf luôn thể

    lỗi 2:
    dùng thêm API FormatMessage để chuyển error code thành string nhé

  3. #3
    Ngày gia nhập
    06 2007
    Bài viết
    18

    Trích dẫn Nguyên bản được gửi bởi nguyentuan2 Xem bài viết
    lỗi 1:
    bạn đã dùng macro _T() thì dùng
    macro _stprintf() thay cho sprintf luôn thể
    Đã khắc phục được lỗi bằng hướng dẫn của bạn. Cảm ơn bạn nguyentuan2 nhé.

    Trích dẫn Nguyên bản được gửi bởi nguyentuan2 Xem bài viết
    lỗi 2:
    dùng thêm API FormatMessage để chuyển error code thành string nhé
    Có một vấn đề là hàm FormatMessage có các tham số sau:
    DWORD FormatMessage( DWORD dwFlags, LPCVOID lpSource, DWORD dwMessageId, DWORD dwLanguageId, LPTSTR lpBuffer, DWORD nSize, va_list* Arguments);

    Ví dụ sử dụng trong MSDN có dạng sau:

    Code:
    DWORD dw = GetLastError(); 
    
        FormatMessage(
            FORMAT_MESSAGE_ALLOCATE_BUFFER | 
            FORMAT_MESSAGE_FROM_SYSTEM,
            NULL,
            dw,
            MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
            (LPTSTR) &lpMsgBuf,
            0, NULL );
    Trong đó dw là biến kiểu DWORD, nhưng trong chương trình CxImage thì hàm GetLastError lại trả về giá trị const char*
    Code:
    const char* CxImage::GetLastError()
    {
    	return info.szLastError;
    }
    Có cách khác ngoài cách sử dụng hàm FormatMessage không bạn nguyentuan2 ơi?
    Đã được chỉnh sửa lần cuối bởi choa : 28-12-2007 lúc 03:43 PM.
    Vouloir C'est pouvoir

  4. #4
    Ngày gia nhập
    12 2007
    Bài viết
    9

    Bạn nên xây dựng một hàm toàn cục để xử lý vấn đề lấy xâu lỗi trả vể. Đây là một đoạn mã mẫu bạn có thể tham khảo:


    HTML Code:
    static TCHAR g_lpszError[1024]; LPTSTR GetLastErrStr(DWORD lastErr/*=0*/) { LPVOID lpMsgBuf; if (lastErr == 0) lastErr = ::GetLastError(); ::FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, NULL, lastErr, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) &lpMsgBuf, 0, NULL ); StringCchPrintf(g_lpszError, 1024, _T("[%d] %s"), lastErr, lpMsgBuf); ::LocalFree(lpMsgBuf); return g_lpszError; } // Usage: if (!::PostMessage(yourWnd, msg, wParam, lParam)) { ::OutputDebugStr(GetLastErrStr()); // or // ::OutputDebugStr(GetLastErrStr(::GetLastError())); }
    Lưu ý:
    - Để tránh xung đột namespace giữa hàm WinAPI với hàm tự viết thì khi gọi hàm API nên thêm chỉ định "::" vào trước tên hàm.

    - Không phải hàm API của nào trong số hàng chục ngàn hàm Windows API cũng dùng được GetLastError() để lấy mã lỗi, chỉ có hàm nào trong tài liệu có chỉ định rõ ràng thì mới dùng được.

  5. #5
    Ngày gia nhập
    08 2006
    Nơi ở
    TpHCM
    Bài viết
    202

    Trong đó dw là biến kiểu DWORD, nhưng trong chương trình CxImage thì hàm GetLastError lại trả về giá trị const char*
    Nếu thế thì bạn sử dụng API MessageBoxA thay vì là AfxMessageBox

  6. #6
    Ngày gia nhập
    06 2007
    Bài viết
    18

    Mặc định Lỗi khi chuyển CxImage sang mã Unicode

    Trích dẫn Nguyên bản được gửi bởi formaT Xem bài viết
    Bạn nên xây dựng một hàm toàn cục để xử lý vấn đề lấy xâu lỗi trả vể.
    Mình đang thử cách của bạn hướng dẫn, hy vọng là được. Cảm ơn bạn đã cho mã nguồn mẫu (đỡ phải tìm kiếm )

    Trích dẫn Nguyên bản được gửi bởi nguyentuan2 Xem bài viết
    Nếu thế thì bạn sử dụng API MessageBoxA thay vì là AfxMessageBox
    Mình đã sử dụng MessageBoxA và kết quả là chạy trơn tru, không báo lỗi nữa. Cảm ơn nhiều nhé.
    Vouloir C'est pouvoir

  7. #7
    Ngày gia nhập
    09 2006
    Bài viết
    711

    Tại sao được vậy, choa giải thích giùm tui một chút xíu, tại sao là A mà không phải là W, và tại sao phải là MessageBoxA mà không AfxMessageBox.
    Thank trước nhé !

  8. #8
    Ngày gia nhập
    06 2007
    Bài viết
    18

    Trích dẫn Nguyên bản được gửi bởi TQN Xem bài viết
    Tại sao được vậy, choa giải thích giùm tui một chút xíu, tại sao là A mà không phải là W, và tại sao phải là MessageBoxA mà không AfxMessageBox.
    Thank trước nhé !
    Cái này thì bạn phải hỏi tác giả là nguyentuan2 ấy. Còn mình chỉ áp dụng hướng dẫn của nguyentuan2 và thấy không còn lỗi nữa.

    Có một điều muốn hỏi các bác là khi để ở cái Encoding Western European (Windows) - Codepage 1252 thì không lỗi. Nhưng khi chuyển sang Unicode (UTF-8 with signature) - Codepage 65001 thì các hàm nào mà có tham số là char * hoặc const char * nhưng khi gọi hàm đó lại truyền tham số là CString chẳng hạn thì đếu báo lỗi. Ví dụ hàm fopen:
    Code:
    FILE *fopen(    const char *filename,   const char *mode )
    Nhưng khi gọi hàm này như sau:
    Code:
    FILE* hfile = fopen(filename,"rb");
    với filename là CString thì lại báo lỗi
    Code:
     C2664: 'fopen' : cannot convert parameter 1 from 'CString' to 'const char *'
    Có ai có cách nào xử lý dứt điểm vụ này không? Cứ sử dụng hàm nào mà tham số là const char * mà lại truyền tham số thực là CString là báo lỗi.
    Đã được chỉnh sửa lần cuối bởi choa : 31-12-2007 lúc 04:57 PM. Lý do: Thêm thông tin
    Vouloir C'est pouvoir

  9. #9
    Ngày gia nhập
    08 2006
    Nơi ở
    TpHCM
    Bài viết
    202

    Để tui giải thích thử nhé:
    Qua lỗi 1 thì thấy rằng cậu ấy đang build mode Unicode
    Qua lỗi thứ 2: AfxMessageBox là 1 generic function, tức là nó tương ứng là 1 trong 2 API MessageBoxA hoặc MessageBoxW
    Vì cậu ấy đang build Unicode nên AfxMessageBox tương đương MessageBoxW
    lúc đó nó chỉ nhận wchar, nên đương nhiên báo lỗi. Mình chỉ cần thay bằng MessageBoxA là được

    Còn về câu hỏi dưới của cậu choa:
    CString là một generic type (MS khoái kiểu này nhỉ). Có lẽ cậu đang sử dụng VS2k3 hoặc VS2k5. Nếu là VC6 thì khắc phục tình trạng trên hơi rườm rà. Từ VS2k3 MFC đã được bổ sung thêm
    CStringA và CStringW (nếu tui nhớ không nhầm) tương ứng với ansi và unicode, còn CString thì vẫn là generic type

    Với những hàm yêu cấu char* hoặc const char*, cậu dùng CStringA. Cậu có thể dùng CString nhưng khi build Unicode, CString tương đương với CStringW, cho nên sẽ gây lỗi
    Với những hàm yêu cấu wchar* hoặc const wchar*, cậu dùng CStringW. Cậu có thể dùng CString nhưng khi build non Unicode, CString tương đương với CStringA, nên sẽ lỗi
    Với những hàm yêu cấu tchar* hoặc const tchar* hoặc (LPTSTR - có chữ T), cậu dùng CString
    Đã được chỉnh sửa lần cuối bởi nguyentuan2 : 01-01-2008 lúc 09:28 AM.

  10. #10
    Ngày gia nhập
    06 2007
    Bài viết
    18

    Bạn nguyentuan2 đã đoán đúng là mình đang dùng VS2k5 và đang build ở mode Unicode. Nhưng khi mình làm theo hướng dẫn của bạn là đối với những hàm yêu cầu char* hoặc const char* thì dùng CStringA. Mình đã dùng thử thì nó kéo theo một loạt các lỗi khai báo và sử dụng biến. Ví dụ như ở post #8, lỗi
    Code:
    C2664: 'fopen' : cannot convert parameter 1 from 'CString' to 'const char *'
    khi sử dụng hàm
    Code:
    FILE* hfile = fopen(filename,"rb");
    với file name là khai báo
    Code:
    CString filename(lpszPathName);
    Thì khi mình sửa lại khai báo biến filename thành:
    Code:
    CStringA filename(lpszPathName);
    nó lại báo lỗi ở dòng sử dụng biến filename:
    Code:
    CString ext(FindExtension(filename));
    với thông tin lỗi:
    Code:
    error C2664: 'CDemoDoc::FindExtension' : cannot convert parameter 1 from 'CStringA' to 'CString'
    ở đây hàm FindExtension có khai báo là
    Code:
    CString FindExtension(CString name);
    Cái CxImage gốc nó viết không theo Unicode nên bây giờ chuyển sang nhiều lỗi quá. Nếu mình trình bày lủng củng, khó hiểu thì mình sẽ upload cái source lên cho mọi người tham khảo và sửa lỗi hộ mình với. Cảm ơn mọi người đã đọc và hướng dẫn cách khắc phục lỗi.
    Vouloir C'est pouvoir

Các đề tài tương tự

  1. Làm thế nào để chuyển đổi Unicode tổ hợp sang Unicode dựng sẳn dùng std::codecvt?
    Gửi bởi doicanhden trong diễn đàn Thắc mắc CTDL & Giải thuật
    Trả lời: 2
    Bài viết cuối: 02-08-2013, 10:27 AM
  2. Kỹ thuật C++ Chuyển tập tin UNICODE sang ASCII?
    Gửi bởi nguyen_thanh.lon trong diễn đàn Thắc mắc lập trình C/C++/C++0x
    Trả lời: 1
    Bài viết cuối: 31-03-2012, 11:45 PM
  3. Kỹ thuật C++ Chuyển Các Ký Tự Từ Mã Unicode sang Mã ASCII
    Gửi bởi nhockcrazy83 trong diễn đàn Thắc mắc lập trình C/C++/C++0x
    Trả lời: 2
    Bài viết cuối: 22-03-2012, 08:20 AM
  4. Chuyển ký tự sang mã unicode trong C#?
    Gửi bởi rambolun trong diễn đàn Thắc mắc lập trình C#
    Trả lời: 2
    Bài viết cuối: 19-03-2011, 02:39 PM
  5. Chuyển Kiểu Unicode sang kiểu số
    Gửi bởi chàng trai dễ thương trong diễn đàn Thắc mắc lập trình Visual C++
    Trả lời: 0
    Bài viết cuối: 25-09-2009, 04:09 PM

Quyền hạn của bạn

  • Bạn không thể gửi đề tài mới
  • Bạn không thể gửi bài trả lời
  • Bạn không thể gửi các đính kèm
  • Bạn không thể chỉnh sửa bài viết của bạn