Посл.ответ |
Сообщение |
Ранг: 36.3 (посетитель) Активность: 0.02↘0 Статус: Участник
|
Создано: 03 марта 2007 11:07 · Личное сообщение · #1
Попытался создать кнопку в виде рисунка, используя следущий код:
#include "stdafx.h"
#include "windows.h"
HINSTANCE hInstance(NULL);
HWND hButton(NULL);
HRGN hRgn (NULL);
WNDPROC oldButtonWndProc;
void RecreateButtonRegion(HWND hWndButton)
{
RECT r;
r.left = 0;
r.top = 0;
r.right = 100;
r.bottom = 25;
hRgn = CreateEllipticRgnIndirect(&r);
SetWindowRgn(hWndButton, hRgn, true);
}
/*void FillSolidRect(HDC dc, LPRECT lpRect)
{
SetBkColor(dc, GetSysColor(COLOR_BTNFACE));
ExtTextOut(dc, 0, 0, ETO_OPAQUE, lpRect, NULL, 0, NULL);
}
void OnButtonPaint(HWND hButtonWnd)
{
HDC dc = GetDC(hButtonWnd);
HWND hWndParent = GetParent(hButtonWnd);
HDC hParentDC = GetDC(hWndParent);
SelectObject(dc, (HBRUSH)GetStockObject(WHITE_BRUSH));
RECT r;
GetClientRect(hButtonWnd, &r);
//FillSolidRect(dc, &r);
BitBlt(dc, r.left, r.top, r.right-r.left, r.bottom-r.top, hParentDC, 0, 0, SRCCOPY);
Ellipse(dc, 0, 0, 99, 25);
ReleaseDC(hWndParent, hParentDC);
ReleaseDC(hButtonWnd, dc);
}
LRESULT CALLBACK ButtonWndProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
{
switch(Msg)
{
case WM_DRAWITEM:
case WM_PAINT:
OnButtonPaint(hWnd);
break;
}
return oldButtonWndProc(hWnd, Msg, wParam, lParam);
}*/
void CreateBitmapRegion(HWND hButton)
{
HBITMAP hButtonBitmap(NULL);
hButtonBitmap = (HBITMAP)LoadImage(hInstance, "button.bmp", IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE|LR_DEFAULTSIZE|LR_LOADTRANSPARENT);
if(hButtonBitmap)
{
HDC wnddc = GetDC(hButton);
HDC dc = CreateCompatibleDC(wnddc);
HDC bmpdc = CreateCompatibleDC(dc);
SelectObject(bmpdc, hButtonBitmap);
// Здесь сканируем всю битмапу с помощью GetPixel, ищем непрозрачные (не черные)
// группы пикселей (получаются прямоугольники высотой 1 пиксель)
// и делаем CombineRgn. Получается мы добавляем маленькие прямоугольнички
// к нашему региону и после того, как мы прошлись по всей битмапе, получаем
// полный регион для кнопки
// А пока просто делаем эллипс
RECT r;
GetWindowRect(hButton, &r);
hRgn = CreateEllipticRgn(0, 0, r.right-r.left, r.bottom-r.top);
DeleteDC(bmpdc);
DeleteDC(dc);
DeleteObject(hButtonBitmap);
ReleaseDC(hButton, wnddc);
}
else
{
RECT r;
GetWindowRect(hButton, &r);
hRgn = CreateEllipticRgn(0, 0, r.right-r.left, r.bottom-r.top);
MessageBox(0, "Error loading bitmap", "Error", 0);
}
}
void OnCreate(HWND hWnd)
{
hButton = CreateWindow("button", "Test", WS_CHILD/*|BS_OWNERDRAW*/, 7,7,100,25, hWnd, NULL, NULL, NULL);
//oldButtonWndProc = (WNDPROC)SetWindowLong(hButton, GWL_WNDPROC, (LONG)ButtonWndProc);
if(!hButton) MessageBox(0, "Error creating button", "Error", 0);
CreateBitmapRegion(hButton);
ShowWindow(hButton, SW_SHOW);
}
void OnPaint(HWND hWnd)
{
HDC dc = GetDC(hWnd);
RECT r;
GetClientRect(hWnd, &r);
//FillSolidRect(dc, &r);
ReleaseDC(hWnd, dc);
}
LRESULT CALLBACK MainWndProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
{
switch(Msg)
{
case WM_CREATE:
OnCreate(hWnd);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
case WM_PAINT:
OnPaint(hWnd);
break;
default:
break;
}
return DefWindowProc(hWnd, Msg, wParam, lParam);
}
int __stdcall WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR lpParams, int nCmdShow)
{
hInstance = hInst;
MSG msg;
WNDCLASS wcx;
HWND hWnd;
wcx.style = CS_HREDRAW|CS_VREDRAW;
wcx.lpfnWndProc = MainWndProc;
wcx.cbClsExtra = 0;
wcx.cbWndExtra = 0;
wcx.hInstance = hInst;
wcx.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wcx.hCursor = LoadCursor(NULL, IDC_ARROW);
wcx.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
wcx.lpszMenuName = NULL;
wcx.lpszClassName = "MainWndClass";
RegisterClass(&wcx);
hWnd = CreateWindow(wcx.lpszClassName, "Test", WS_DLGFRAME|WS_SYSMENU, 100,100,400,300, NULL, NULL, hInst, NULL);
ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);
RecreateButtonRegion(hButton);
UpdateWindow(hButton);
while (GetMessage(&msg, (HWND) NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
return 0;
}
Только вот при первом запуске не наблюдаю мою, заранее заготовленную BMP - ху, вижу только некую овальную область на месте кнопки и при щелчке по ней появляется кнопка... (((((
Так всё же как быть с кнопкой которую хочу вставить в виде рисунка?
Помогите пожалуйста!
| Сообщение посчитали полезным: |
|
Ранг: 310.8 (мудрец), 29thx Активность: 0.43↘0 Статус: Участник
|
Создано: 03 марта 2007 22:31 · Личное сообщение · #2
sxd пишет:
Так всё же как быть с кнопкой которую хочу вставить в виде рисунка?
Так я не понял что появляется при щелчке ? Кнопки сначала нет, т.к. ты не прорисовал ее. Для стандартных кнопок метод для рисования там автоматом торчит, для нестандартных придется самому.
Или даже скорее окно думает сначала, что все уже нарисовано. Тогда надо InvalidateRect сделать.
Если же в овале появляется стадартная кнопка, то значит ты не перекрыл ее метод рисования, т.е. просто ошибся где-то. Разбираться в сырце лень, т.к. давно уже есть стандартные штучки на это дело.
| Сообщение посчитали полезным: |
Ранг: 516.1 (!), 39thx Активность: 0.28↘0 Статус: Участник
|
Создано: 04 марта 2007 02:11 · Личное сообщение · #3
смотрим в примеры в masm'e, там было что-то подобное
| Сообщение посчитали полезным: |
Ранг: 36.3 (посетитель) Активность: 0.02↘0 Статус: Участник
|
Создано: 04 марта 2007 04:30 · Личное сообщение · #4 |
Ранг: 23.8 (новичок) Активность: 0.01↘0 Статус: Участник
|
Создано: 04 марта 2007 18:36 · Личное сообщение · #5
Ну первое что пришло на ум - www.codeproject.com/buttonctrl/#Non%2Drectangular+Buttons
| Сообщение посчитали полезным: |
Ранг: 73.1 (постоянный), 130thx Активность: 0.04↗0.23 Статус: Участник
|
Создано: 04 марта 2007 23:52 · Личное сообщение · #6
sxd, тебе ж уже сказали: посмотри примеры в MASM'е, там 100% есть то, что тебе нужно.
| Сообщение посчитали полезным: |
Ранг: 135.2 (ветеран) Активность: 0.07↘0 Статус: Участник
|
Создано: 05 марта 2007 00:18 · Личное сообщение · #7
RamMerlabs пишет:
тебе ж уже сказали: посмотри примеры в MASM'е, там 100% есть то, что тебе нужно.
Да, в MASM32 есть пример BitmapButton. Я сам как-то его переписал на дельфи и юзал, думаю, что на С++ переписать тоже не сложно
| Сообщение посчитали полезным: |
Ранг: 36.3 (посетитель) Активность: 0.02↘0 Статус: Участник
|
Создано: 05 марта 2007 08:17 · Личное сообщение · #8
Я asma жутко боюсь, предпринимал несколько атак на его штурм, но он не преступен.... ))) так много вопросов возникает по архитектуре, а спросить и объяснить некому... ((( Поэтому не ругайте строго )), я же не специально.
А что касается кнопки хотел спросить как всё же лучше реализовать, вот допустим есть окно синего цвета, на нём хочу сделать красную элипсовидную кнопку в виде прямоугольного рисунка, то есть кнопка по сути квадратная но BMP кнопки - Красный элипс на синем фоне, но тут проблема, как я думаю, это не даст желаемого результата, так как хотелось сделать так чтоб кнопка была в виде BMP - хи, но когда на неё наводил курсор кнопка как бы приподнималась (это конечно в идеале))), и так как я понял всё-таки кнопка должна быть не стандартной, т.е. овальной и быть в виде рисунка?
| Сообщение посчитали полезным: |
Ранг: 36.3 (посетитель) Активность: 0.02↘0 Статус: Участник
|
Создано: 06 марта 2007 09:08 · Личное сообщение · #9
sataron пишет:
Ну первое что пришло на ум - www.codeproject.com/buttonctrl/#Non%2Drectangular+Buttons
Ну да как же один MFC, чё на API нельзя было сделать или все только на MFC умеют!
| Сообщение посчитали полезным: |
Ранг: 310.8 (мудрец), 29thx Активность: 0.43↘0 Статус: Участник
|
Создано: 07 марта 2007 05:26 · Личное сообщение · #10
sxd пишет:
когда на неё наводил курсор кнопка как бы приподнималась
Отрабатываешь событие курсор над кнопкой(в ее области) и меняешь картинку. Картинку лучше заранее приготовить, чтобы не было тормозов.
| Сообщение посчитали полезным: |
Ранг: 36.3 (посетитель) Активность: 0.02↘0 Статус: Участник
|
Создано: 07 марта 2007 08:48 · Личное сообщение · #11
tundra37 пишет:
Отрабатываешь событие курсор над кнопкой(в ее области) и меняешь картинку. Картинку лучше заранее приготовить, чтобы не было тормозов.
Да это понятно... Ну всё же как BMP вставить в кнопку, без всяких классов... , без MFC...
| Сообщение посчитали полезным: |
Ранг: 20.8 (новичок) Активность: 0.01↘0 Статус: Участник
|
Создано: 09 марта 2007 05:51 · Личное сообщение · #12
Ну на крайний случай - с помощью GetWindowLong - получаем адрес процедуры окна, пишем свою, в которой при OnPaint - рисуем нужный bitmap, а затем вызываем старую процедуру, и с помощью SetWindowLong - устанавливаем новую процедуру для окна, а вообще MFC в исходниках поставляется там всё можно посмотреть.
| Сообщение посчитали полезным: |
Ранг: 36.3 (посетитель) Активность: 0.02↘0 Статус: Участник
|
Создано: 09 марта 2007 08:51 · Личное сообщение · #13
Спасибо конечно за совет, но лучше кто-нибудь кодом поделился....
| Сообщение посчитали полезным: |
Ранг: 516.1 (!), 39thx Активность: 0.28↘0 Статус: Участник
|
Создано: 10 марта 2007 04:36 · Личное сообщение · #14
sxd, готов платить?
| Сообщение посчитали полезным: |
Ранг: 81.2 (постоянный) Активность: 0.04↘0 Статус: Участник
|
Создано: 11 марта 2007 22:10 · Личное сообщение · #15
если подойдёт дельфа то сходи на королество (dekphikingdom.ru) там по ходу я брал что-то
только не помню где в 200 Гг находиться эта радость
| Сообщение посчитали полезным: |
Ранг: 7.0 (гость) Активность: 0=0 Статус: Участник
|
Создано: 12 марта 2007 08:05 · Личное сообщение · #16
вот пример GFX проги + сорсы, есть все что тебе нужно...
я когдато мутил там еще и jpg используется. - GFXApp.rar
| Сообщение посчитали полезным: |
Ранг: 5.0 (гость) Активность: 0=0 Статус: Участник
|
Создано: 13 марта 2007 21:54 · Поправил: -=The Bone=- · Личное сообщение · #17
sxd пишет
Да это понятно... Ну всё же как BMP вставить в кнопку, без всяких классов... , без MFC...
Чистый API - что-то типа такого (описания функций найдешь в Win32SDK - оно у тебя есть,
если у тебя есть Borland C++/Delphi):
int WINAPI BtnProc(HWND hWnd, int Msg, int wparam, int lparam)
{HDC hdc, idc, vdc;
int tmp;
HBITMAP hBmp;
PAINTSTRUCT ps;
switch (msg)
// грузишь картинку и создаешь ей DC с регионами
{case WM_CREATE:
hdc=GetDC(hWnd);
hBmp=LoadImage(//имя файла картинки + fuLoad=LR_LOADFROMFILE | LR_CREATEDIBSECTION);
idc=CreateCompatibleDC(hdc);
vdc=CreateCompatibleDC(hdc);
SelectObject(idc, hBmp);
SelectObject(vdc, CreateCompatibleBitmap(hdc, /* your Widht */, /* your Height */);
PatBlt(vdc, 0, 0, /* your Widht */, /* your Height */, GetStockObject(NULL_BRUSH));
/* работаешь с регионами в idc с копирование всего наработанного в vdc */
// ...
DeleteDC(idc);
ReleaseDC(hWnd, hdc);
CloseHandle(hBmp);
SetWindowLong(hWnd, GWL_USERDATA, vdc);
// теперь в vdc - исходная картинка
UpdateWindow(hWnd); // самоперерисовка
break;
case WM_PAINT:
hdc=BeginPaint(hWnd, &ps);
BitBlt(hdc, /* your x */, /* your y */, /* your Widht */, /* your Height */,
GetWindowLong(hWnd, GWL_USERDATA)
, /* your x in vdc or 0 */, /* your y in vdc or 0 */, SRCCOPY);
EndPaint(hWnd, &ps);
break;
case WM_DESTROY:
DeleteDC(GetWindowLong(hWnd, GWL_USERDATA)); break;
default: DefWindowProc(hWnd, msg, wparam, lparam);
}
return (1);
}
где-то на 20% сложнее, но на 25% гибче...
| Сообщение посчитали полезным: |
Ранг: 36.3 (посетитель) Активность: 0.02↘0 Статус: Участник
|
Создано: 19 марта 2007 19:54 · Личное сообщение · #18 |