M­­ar­­­­k Ответов: 2

Проблема с кнопкой Win32


Я хочу добавить кнопку в свое окно..
И вот код, который я попробовал..

#include <Windows.h>
#include <tchar.h>

LRESULT CALLBACK winproc(HWND, UINT, WPARAM, LPARAM);


int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR cmdLine, int cmdShow)
{
	TCHAR className[] = _T("button test");

	WNDCLASS winclass;
	winclass.cbClsExtra = 0;
	winclass.cbWndExtra = 0;
	winclass.hbrBackground = static_cast<HBRUSH>(GetStockObject(LTGRAY_BRUSH));
	winclass.hCursor = LoadCursor(NULL, IDC_CROSS);
	winclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
	winclass.hInstance = hInstance;
	winclass.lpfnWndProc = winproc;
	winclass.lpszClassName = className;
	winclass.lpszMenuName = NULL;
	winclass.style = CS_VREDRAW | CS_HREDRAW;

	RegisterClass(&winclass);

	HWND hWnd = CreateWindow(className, className,
		WS_OVERLAPPEDWINDOW,
		100, 100, 500, 500,
		NULL, NULL, hInstance, NULL);

	ShowWindow(hWnd, cmdShow);

	MSG msg;
	while (GetMessage(&msg, hWnd, 0, 0))
	{
		TranslateMessage(&msg);
		DispatchMessage(&msg);
	}
	return msg.wParam;
}

LRESULT CALLBACK winproc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
	if (message == WM_CREATE)
	{
		HWND hWndButton = CreateWindow(TEXT("BUTTON"), TEXT("btn"),
			WS_CHILD | WS_VISIBLE | BS_PUSHBOX,
			10, 10, 100, 25,
			hWnd, NULL, (HINSTANCE)GetWindowLong(hWnd, GWL_HINSTANCE), NULL);
	}
	if (message == WM_COMMAND)
	{
		MessageBox(hWnd, _T(""), _T(""), MB_OK);
	}

	return DefWindowProc(hWnd, message, wParam, lParam);
}


а вот снимок экрана моего окна

[ИМГ]http://i61.tinypic.com/2gxelxi.png[/ИМГ]

http://i61.tinypic.com/2gxelxi.png[^]

он даже не отправляет WM_COMMAND, когда я нажимаю на него.. что не так с моим кодом ?

заранее спасибо !

enhzflep

Из справки MSDN для BS_PUSHBOX:

"Оператор определения ресурса PUSHBOX создает элемент управления push-box, который идентичен кнопке, за исключением того, что он не отображает грань кнопки или рамку; появляется только текст."

Когда я удаляю стиль BS_PUSHBUTTON и строю I
(а) получить кнопку с текстом на ней
и
(b) получить WM_COMMAND, когда он нажат.

Я часто использую ResEdit - как для создания реальных ресурсов, так и для быстрого создания кода, необходимого для создания элемента управления/шрифта с нуля. Создав фиктивный диалог и добавив нужный элемент управления, а затем выбрав File->Code Preview->C++ Source.

M­­ar­­­­k

я изменился, как ты и сказал.. Но я все еще не получаю сообщение WM_COMMAND

enhzflep

Хорошо, тогда что же говорит вам Spy++ (или вариант не ms), когда вы нажимаете кнопку. Попробуйте прослушивать сообщения как в главном окне, так и на самой кнопке. Вы можете отфильтровать сообщения, чтобы возвращать только WM_COMMAND (или, по крайней мере, исключить WM_MOUSEMOVE, WM_NCHITTEST и WM_SETCURSOR)

Когда я настроен на прослушивание главного окна и исключаю все сообщения, кроме WM_COMMAND, я получаю следующие строки, представленные при нажатии кнопки: (вместе с пустым полем сообщения отображается)

<00001> 00320520 S WM_COMMAND wNotifyCode:BN_CLICKED wID:0 hwndCtl:0024106
<00002> 00320520 R WM_COMMAND

Единственное изменение, которое я сделал из вашего источника, как было опубликовано, - это удалить стиль BS_PUSHBOX. У меня все еще есть текст("кнопка") в качестве класса, и, как вы можете видеть, у меня все еще есть идентификатор элемента управления 0.

Построен с использованием mingw32-g++ (4.7.something) и работает на win7

2 Ответов

Рейтинг:
2

Richard MacCutchan

Вам нужно добавить идентификатор команды к вашей кнопке (кнопки выглядят лучше, чем коробки), например:

HWND hWndButton = CreateWindow(TEXT("BUTTON"), TEXT("Push Me"),
    WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON,
    10, 10, 100, 25,
    hWnd, (HMENU)ID_MYCOMMAND, (HINSTANCE)GetWindowLong(hWnd, GWL_HINSTANCE), NULL);

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


M­­ar­­­­k

- Добавил я.. Но я все еще не получаю никаких сообщений WM_COMMAND....

Richard MacCutchan

Ну, вы, должно быть, делаете что-то не так, это прекрасно сработало для меня, для обоих BS_PUSHBUTTON и BS_PUSHBOX.

Richard MacCutchan

И просто чтобы убедиться, я скопировал ваш код, добавил идентификационное значение (просто большое число) к CreateWindow для кнопки, и она работала правильно.

Рейтинг:
1

nv3

Просто предположение: чтобы иметь возможность отправить сообщение WM_COMMAND, кнопка нуждается в идентификаторе. Для диалогов на основе шаблонов этот идентификатор обычно исходит из шаблона. В вашем случае вы должны установить вручную, например:

SetWindowLong (m_hWnd, GWL_ID, 100); // sets id 100


[Добавлено] еще один возможный источник ошибок заключается в том, что Вы указали класс окна "BUTTON" во всех прописных буквах. Вместо этого вы должны попробовать "кнопку".


M­­ar­­­­k

Это ничего не меняет..
Я все еще не получаю сообщение WM_COMMAND

nv3

Хорошо, смотрите мой текст выше для еще одной попытки.

Richard MacCutchan

Имена классов не чувствительны к регистру; смотрите мои последние комментарии ниже.

nv3

О, вы совершенно правы. Кажется, он делает что-то не так, но что?

Richard MacCutchan

Ну, как и со многими другими вопросами, мы получаем только половину истории. :/