Почему мои вызовы Win32 API требуют суффикса 'A', и я должен исправить это? - PullRequest
1 голос
/ 29 августа 2011

Для выполнения команды из оболочки Win мне понадобилось

ShellExecuteA(NULL, "open", "http://stackoverflow.com", NULL, NULL, SW_SHOWNORMAL);

и сейчас я работаю с помощью Forgers Win32 Tutorial. Я нахожу суффикс A, необходимый для предотвращения вывода мусора на экран. Я знаю, что это связано с форматом символов, по умолчанию в моей ОС. Если бы я мог «нормализовать» свою ОС, это могло бы стать лучшим решением, потому что я получаю NULL из RegisterClassExA независимо от того, сколько функций * A я использую во втором примере (воспроизведено ниже с добавленными мной суффиксами llloottttssss * A)

#include <windows.h>
const wchar_t g_szClassName[] = L"myWindowClass";
// Step 4: the Window Procedure
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{/*...*/
    return 0;
}
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
    LPSTR lpCmdLine, int nCmdShow)
{
    WNDCLASSEX wc;
    HWND hwnd;
    MSG Msg;
    //Step 1: Registering the Window Class
    wc.cbSize        = sizeof(WNDCLASSEX);
    wc.lpfnWndProc   = WndProc;
    wc.cbClsExtra    = 0;
    wc.cbWndExtra    = 0;
    wc.hInstance     = hInstance;
    wc.hIcon         = LoadIcon(NULL, IDI_APPLICATION);
    wc.hCursor       = LoadCursor(NULL, IDC_ARROW);
    wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
    wc.lpszMenuName  = NULL;
    wc.lpszClassName = g_szClassName;
    wc.hIconSm       = LoadIcon(NULL, IDI_APPLICATION);
    if(!RegisterClassEx(&wc))
    {
        MessageBox(NULL, L"Window Registration Failed!", L"Error!",
        MB_ICONEXCLAMATION | MB_OK);
    return 0;
    }
    // Step 2: Creating the Window...
    return Msg.wParam;
}

Я пересмотрел приведенный выше код, чтобы сделать его похожим на Forgers (убрал * A), и вместо этого использовал L"" инициализаторы строк, но теперь я получаю ошибку, присваивая const char g_szClassName[] = L"myWindowClass";

ошибка C2053: 'g_szClassName': несоответствие широкой строки

Замена char на wchar создает сообщения об ошибках компилятора, указывающие, что wchar не является распознанным типом.

_ EDIT _

Я полагаю, что спецификатор строки L"" является предпочтительным решением, и я хотел бы продолжить его, извините, если мой вопрос, кажется, бьется вокруг куста, я открыт для предложений.

Просто обновил этот код до того, что я сейчас использую, и вырезал то, чего не могу достичь.

_ EDIT _

Код ошибки - 87, недопустимый параметр, поэтому я полагаю, что назначение параметра wchar_t ( wc.lpszClassName = g_szClassName;) в конце концов неверно ...: @ (

_ EDIT _

Не угадал ?! const LPCTSTR g_szClassName = L"myWindowClass"; не исправил (или сломал) вещь.

Ответы [ 3 ]

3 голосов
/ 29 августа 2011

Большинство вызовов WinAPI доступны в двух вариантах: SomeFunctionA - это односимвольная версия (т. Е. С использованием char[] для строк), SomeFunctionW - версия с широкими символами (т. Е. С использованием wchar_t[] для строк).Обычно существует макрос, определенный без этого суффикса (в данном случае SomeFunction), который будет содержать либо SomeFunctionA, либо SomeFunctionW в зависимости от настройки юникода вашего проекта.Аналогичным образом есть макрос _T, который примет ваши строковые литералы и добавит ведущий L в случае использования юникода.

Чтобы подобрать исходный пример, этот код должен работать со всеми настройками(хотя и не проверено):

ShellExecute(NULL, _T("open"), _T("http://stackoverflow.com"), NULL, NULL, SW_SHOWNORMAL); 
1 голос
/ 29 августа 2011

Если вам нужна строка в юникоде, ключевое слово будет wchar_t

const wchar_t g_szClassName[] = L"myWindowClass";

Edit:

Кроме того, убедитесь, что вы инициализируете нулем остальные элементы структуры WNDCLASSEX, которые вы не установили, т.е.

WNDCLASSEX wc = {};

OR

ZeroMemory(&wc, sizeof(wc));
0 голосов
/ 29 августа 2011

Добавить эту строку:

wc.style = CS_HREDRAW | CS_VREDRAW;
...