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é
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
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(m_text.lfont.lfFaceName, GetProfileString( _T("TextTool"), _T("lfFaceName"), _T("Arial")) );
nhưng vẫn không khắc phục được lỗi.Code:sprintf((char *)m_text.lfont.lfFaceName, GetProfileString( _T("TextTool"), _T("lfFaceName"), _T("Arial")) );
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:
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á.Code:if (!newImage->LoadResource(FindResource(NULL,MAKEINTRESOURCE(IDB_BITMAP1),RT_BITMAP),CXIMAGE_FORMAT_BMP)){ AfxMessageBox(newImage->GetLastError());
Đã đượ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
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é
Đã khắc phục được lỗi bằng hướng dẫn của bạn. Cảm ơn bạn nguyentuan2 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:
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:DWORD dw = GetLastError(); FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, NULL, dw, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) &lpMsgBuf, 0, NULL );
Có cách khác ngoài cách sử dụng hàm FormatMessage không bạn nguyentuan2 ơi?Code:const char* CxImage::GetLastError() { return info.szLastError; }
Đã được chỉnh sửa lần cuối bởi choa : 28-12-2007 lúc 03:43 PM.
Vouloir C'est pouvoir
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:
Lưu ý: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())); }
- Để 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.
Nếu thế thì bạn sử dụng API MessageBoxA thay vì là AfxMessageBoxTrong đó 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*
Vouloir C'est pouvoir
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:
Nhưng khi gọi hàm này như sau:Code:FILE *fopen( const char *filename, const char *mode )
với filename là CString thì lại báo lỗiCode:FILE* hfile = fopen(filename,"rb");
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.Code:C2664: 'fopen' : cannot convert parameter 1 from 'CString' to 'const char *'
Đã đượ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
Để 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.
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
khi sử dụng hàmCode:C2664: 'fopen' : cannot convert parameter 1 from 'CString' to 'const char *'
với file name là khai báoCode:FILE* hfile = fopen(filename,"rb");
Thì khi mình sửa lại khai báo biến filename thành:Code:CString filename(lpszPathName);
nó lại báo lỗi ở dòng sử dụng biến filename:Code:CStringA filename(lpszPathName);
với thông tin lỗi:Code:CString ext(FindExtension(filename));
ở đây hàm FindExtension có khai báo làCode:error C2664: 'CDemoDoc::FindExtension' : cannot convert parameter 1 from 'CStringA' to 'CString'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.Code:CString FindExtension(CString name);
Vouloir C'est pouvoir