MyOldAccount Ответов: 2

Как я могу создать кнопку, показывающую значок и текст, используя BS_ICON и отправляя BM_SETIMAGE?


Привет всем!

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

Мне нужно сделать кнопку, которая является дочерним элементом главного окна со следующими характеристиками:

- Он имеет синий фон;
- I отображает значок;
- Он отображает текст под значком;
- Текст должен быть выделен жирным шрифтом;
- Текст на сербско-кириллическом языке;

Что касается текста, то я знаю, что есть стиль BS_BOTTOM для отображения его в нижней части кнопки, и есть функция SetFont (), чтобы сделать его жирным, но я не знаю, как заставить его принимать кириллические символы ( пример кода был бы очень признателен ).

Что касается части icon + text, то это то, что я пробовал до сих пор:

***********************************************************************************

Обновление №1: опубликовал весь код в надежде помочь другим быстрее найти решение.

************************************************************************************

Ресурса.ч
******************************************************
#ifndef IDC_STATIC
#define IDC_STATIC (-1)
#endif

#определить IDI_ICON1 100
*******************************************************

main.cpp
*******************************************************

#include "resource.h"
#include <windows.h>

static HINSTANCE hInst;

// icon for desktop, ALT +TAB ... ( this same icon shall be used temporally for testing button )

static HICON hIcon; 

// WinMain's procedure

LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{

	switch(msg)
	{

	case WM_CREATE:
		
		{
			HWND hbtnUnosPodataka = CreateWindowEx(0, "Button", "Geotermist", WS_VISIBLE | WS_CHILD |  BS_TEXT | BS_BOTTOM, 100, 100,150, 150, hwnd, (HMENU)4000, hInst, 0);

			HICON hIcon1 = LoadIcon( hInst, MAKEINTRESOURCE(IDI_ICON1));
			
			SendMessage( hbtnUnosPodataka , BM_SETIMAGE, (WPARAM)IMAGE_ICON, (LPARAM)hIcon1);
		
		}
		break;

	case WM_CLOSE:

		DestroyWindow(hwnd);

		break;

	case WM_DESTROY:

		PostQuitMessage(0);

		break;

	default:
		return DefWindowProc(hwnd, msg, wParam, lParam);
	}
	return 0;
}

// WinMain

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,LPSTR lpCmdLine, 
				   int nCmdShow)
{
	// store hInstance in global variable

	hInst = hInstance;
	
	// load main window's icon - this same icon shall be used for testing the button

	hIcon = LoadIcon( hInst, MAKEINTRESOURCE(IDI_ICON1));

	WNDCLASSEX wc;
	HWND hwnd;
	MSG Msg;

	wc.cbSize = sizeof(WNDCLASSEX);
	wc.style = 0;
	wc.lpfnWndProc = WndProc;
	wc.cbClsExtra = 0;
	wc.cbWndExtra = 0;
	wc.hInstance = hInstance;
	wc.hIcon = hIcon;
	wc.hCursor = LoadCursor(NULL, IDC_ARROW);
	wc.hbrBackground = (HBRUSH)GetStockObject(LTGRAY_BRUSH); 
	wc.lpszMenuName = NULL;
	wc.lpszClassName = "Main_Window";
	wc.hIconSm = hIcon;

	if(!RegisterClassEx(&wc))
	{
		MessageBox(NULL, "Window Registration Failed!", "Error!", MB_ICONEXCLAMATION | 
			MB_OK);

		return 0;
	}

	// main window

	hwnd = CreateWindowEx(WS_EX_CLIENTEDGE, "Main_Window", "Geotermist",
		WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
		CW_USEDEFAULT, NULL, NULL, hInstance, NULL);

	if(hwnd == NULL)
	{
		MessageBox(NULL, "Window Creation Failed!", "Error!", MB_ICONEXCLAMATION | MB_OK);
		return 0;
	}

	ShowWindow(hwnd, nCmdShow);
	UpdateWindow(hwnd);

	while(GetMessage(&Msg, NULL, 0, 0) > 0)
	{
		TranslateMessage(&Msg);
		DispatchMessage(&Msg);
	}

	return Msg.wParam;
}


В MSDN указано, что для того, чтобы кнопка отображала значок и текст, BS_BITMAP или BS_ICON не должны быть установлены, и я должен отправить BM_SETIMAGE.

Я пытался это сделать, но ничего не вышло.

Я работаю в MS Visual Studio Express 2008, на Windows XP, на C++, используя WIN32 API. Если вам потребуется какая-либо другая информация ( исходный код или что-то подобное ), пожалуйста, попросите ее, я с удовольствием предоставлю ее вам.

2 Ответов

Рейтинг:
2

Member 12531282

Если вы столкнетесь с этой проблемой в 2018 году - > вам просто нужно сначала включить визуальный стиль!
Тогда разнесенные коды должны работать.

Ссылка:
Включение Визуальных Стилей | Microsoft Docs[^]


Рейтинг:
14

Richard MacCutchan

Следующий код работал для меня, используя либо значок, либо растровое изображение :

HINSTANCE		hInstance = GetModuleHandle(NULL);
hButton = CreateWindowEx(0, L"Button", L"АБВГДЕЖЗ", WS_VISIBLE | WS_CHILD | BS_TEXT | BS_BOTTOM, 100, 100, 150, 150, hWnd, (HMENU)4000, hInstance, 0);

// use an icon
HICON hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDR_MAINFRAME));
SendMessage(hButton, BM_SETIMAGE, (WPARAM)IMAGE_ICON, (LPARAM)hIcon);

// or use a bitmap
HANDLE hBitmap = LoadImage(hInstance, MAKEINTRESOURCE(IDR_BUTTON), IMAGE_BITMAP, 0, 0, LR_DEFAULTCOLOR);
SendMessage(hButton, BM_SETIMAGE, (WPARAM)IMAGE_BITMAP, (LPARAM)hBitmap);

У меня есть нет пробовал кириллические символы , но я бы догадался вам просто нужно отправить их в третьем параметре программы. CreateWindowEx вызов, после установки кириллического шрифта.

[редактировать]
Кириллица тоже отлично работает.
[/редактировать]


MyOldAccount

Я внес коррективы в соответствии с вашим решением, но оно не работает для меня.

Можете ли вы опубликовать весь свой код или я должен опубликовать свой ( он не такой большой), чтобы мы могли увидеть, чего не хватает?

Спасибо.

Richard MacCutchan

Это весь мой код с точки зрения отображения кнопки. Он создает кнопку в главном окне очень простого приложения Windows. Я действительно обнаружил, что BS_BOTTOM стиль применяется к изображению, нарисованному на кнопке, а не к тексту.

Может быть, вам стоит показать, что вы сделали. Но, пожалуйста, не публикуйте его в качестве ответа на это сообщение; используйте ссылку "улучшить вопрос" выше и добавьте его туда.

MyOldAccount

Я сделал так, как вы мне сказали.
Надеюсь, что это поможет.
Спасибо.

Richard MacCutchan

Спасибо, это позволило мне скопировать ваш код в VS и построить его. И знаете что, он отлично работает! Однако это было использование VS2010 в Windows 7; я попробую VS2008, но, вероятно, не раньше завтрашнего дня.

Можете ли вы попытаться объяснить более подробно, что именно происходит, когда вы это делаете?

MyOldAccount

Спасибо, да, я могу объяснить.

Он отображает текст нормально, но нет никакого значка.

Я подозреваю, что это вина Visual Studio, так как я использую free edition, и у него есть некоторые ограничения, такие как недоступность редактора ресурсов, поэтому я должен использовать альтернативный вариант.

Возможно, это просто еще одна часть, которую Microsoft пропустила из free edition.

Richard MacCutchan

Я также использую Экспресс-издание, и оно отлично работает. Вы уверены, что ваш значок правильно включен и встроен в ваши ресурсы?

Richard MacCutchan

Мне удалось протестировать это с помощью VS 2008 Express edition на Windows XP, и это действительно так нет работа. Кажется, вы можете получить изображение или текст, но не оба. Я не уверен, является ли это проблемой Windows или Visual Studio. Вы можете попробовать перейти на VS 2010 Express и посмотреть, работает ли он тогда.

MyOldAccount

Еще хуже обстоит дело с Express Edition 2010.
Я получаю те же симптомы, когда комментирую комментарий #pragma, но если я оставляю его, кнопка вообще не отображается!
Я постараюсь достать профессиональное издание, и посмотрим, что тогда получится.

Richard MacCutchan

Да, я обнаружил это; очень странно. Однако я уверен, что это больше связано с версией Windows, чем с Visual Studio. Как я уже сказал выше, ваш код отлично работает под Windows 7, я получаю изображение и текст.

MyOldAccount

Он работает с Express Edition 2008 на Windows 7.
Я думаю, что это что-то с XP...
В любом случае,спасибо вам за то,что вы действительно пытаетесь помочь, поэтому я отмечу эту тему как решенную, приняв ваше решение.
Просто обновите свое решение, чтобы включить кириллический шрифт, пожалуйста!
Это важно ( код или псевдокод или простые инструкции подойдут )!

Richard MacCutchan

Я думаю, что документация Microsoft не является актуальной.

Я уже поместил кириллические символы в вышеприведенное решение; вам просто нужно использовать строки Unicode.

MyOldAccount

Часть UNICODE - это то, что меня беспокоит.
Как включить Юникод?
Мне неловко спрашивать, но после того, как я набираю #include <tchar.h> Я все еще получаю ошибки.

Richard MacCutchan

Извините, я должен был объяснить, что вы установили Unicode в Visual Studio. Щелкните правой кнопкой мыши на вашем проекте в обозревателе решений, затем выберите пункт Свойства, перейдите в раздел Общие -> набор символов и выберите пункт Use Unicode Character Set.

MyOldAccount

Я сделал это, и MS VISUAL C++ сообщила об ошибке, создав новое окно со следующей информацией:

-------------------------------------------------------
Некоторые символы юникода в этом файле не могут быть сохранены в текущей кодовой странице.
Вы хотите повторно сохранить этот файл в формате UNICODE, чтобы сохранить ваши данные?
-------------------------------------------------------

Должен признаться, я этого не ожидал... Есть идеи?

Richard MacCutchan

Это потому, что у вас есть символы Юникода в вашей строке и, следовательно, в исходном файле. Visual Studio просто нужно преобразовать исходный код в Юникод, поэтому вы должны ответить " да " на это сообщение.

MyOldAccount

Это сработало!
БОЛЬШОЕ ВАМ СПАСИБО!
ДА БЛАГОСЛОВИТ ВАС БОГ!

Richard MacCutchan

С удовольствием, желаю удачи с остальной частью вашего проекта.