Форум программистов, компьютерный форум, киберфорум
C/C++: WinAPI
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.83/63: Рейтинг темы: голосов - 63, средняя оценка - 4.83
23 / 23 / 7
Регистрация: 30.01.2009
Сообщений: 103

Кнопка со стилем BS_OWNERDRAW

07.05.2011, 22:54. Показов 12385. Ответов 15
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Помогите разобраться с BS_OWNERDRAW нашел вот http://social.msdn.microsoft.c... 7343689dc/, но что не работает кнопка не отображается. В чем может быть загвоздка?
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
07.05.2011, 22:54
Ответы с готовыми решениями:

Кнопка BS_OWNERDRAW или кнопка со своей картинкой
Есть код, с помощью которого можно менять картинку при нажатии, при фокусе { // ownerdraw button static HBITMAP no_active; ...

Создание своей кнопки BS_OWNERDRAW
Добрый день. Нужно нарисовать свою кнопку (сделать прозрачной, без полей и прочего). Знаю, что нужно создать кнопку со стилем BS_OWNERDRAW...

Кнопка со стилем
Добрый день, не подскажите новичку как сделать кнопку со стилем, по нажатию на которую бы открывалась еще одна кнопка.

15
 Аватар для resource2008
111 / 112 / 18
Регистрация: 11.03.2011
Сообщений: 421
13.05.2011, 00:23
"Do not combine the BS_OWNERDRAW style with any other button styles."

условие учтено?
0
23 / 23 / 7
Регистрация: 30.01.2009
Сообщений: 103
13.05.2011, 01:52  [ТС]
создаю кнопку с такими стилями WS_CHILD | BS_OWNERDRAW
0
 Аватар для resource2008
111 / 112 / 18
Регистрация: 11.03.2011
Сообщений: 421
13.05.2011, 02:27
можно код сюда выложить?
0
53 / 53 / 2
Регистрация: 06.04.2011
Сообщений: 209
13.05.2011, 11:25
создаю кнопку с такими стилями WS_CHILD | BS_OWNERDRAW
Попробуй добавить стиль WS_VISIBLE.
0
23 / 23 / 7
Регистрация: 30.01.2009
Сообщений: 103
13.05.2011, 13:02  [ТС]
Вот код
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
#include <windows.h>
 
 
#define  ID_BUTTON  1000
#define  IDR_BUTTONUP  1001
#define  IDR_BUTTONDOWN    1002
#define  IDR_BUTTONGR      1003
 
/*  Declare Windows procedure  */
LRESULT CALLBACK WindowProcedure (HWND, UINT, WPARAM, LPARAM);
void DrawBitmap(HDC hDC, int x, int y, HBITMAP hBitmap);
 
/*  Make the class name into a global variable  */
char szClassName[ ] = "WindowsApp";
HWND hwnd, hRecord;
 
HINSTANCE GetAppHinstance(HWND hWnd)
{
    char lpClassName[1024]="";
    if (!GetClassName(hWnd,lpClassName,sizeof(lpClassName))) return NULL;
    WNDCLASSEX wndcx;
    memset(&wndcx,0,sizeof(wndcx));
    if (!GetClassInfoEx(NULL, lpClassName,&wndcx)) return NULL; //Fails here
    return wndcx.hInstance;
}
 
void DrawButton(LPDRAWITEMSTRUCT lpInfo)
{
    HBITMAP hbm;
    int ResourceID;
 
    // Обрабатываем сообщение WM_DRAWITEM
    // только если оно поступило от кнопки 
    if(lpInfo->CtlType != ODT_BUTTON)
        return;
 
    // Так как в приложении может быть несколько
    // кнопок, посылающих сообщение WM_DRAWITEM,
    // проверяем идентификатор кнопки
    switch (lpInfo->CtlID)
    {
    case ID_BUTTON:
        {
            // Загружаем идентификатор изображения
            // кнопки в нормальном (отжатом) состоянии
            ResourceID = IDR_BUTTONUP;
            break;
        }
    default:
        return;
    }
 
    // Если кнопка выбрана, рисуем ее в нажатом
    // состоянии
    if (lpInfo->itemState & ODS_SELECTED)
    {
        ResourceID = IDR_BUTTONDOWN;
    }
 
    // если кнопка неактивна, загружаем идентификатор
    // изображения кнопки в неактивном состоянии
    else if (lpInfo->itemState & ODS_DISABLED)
    {
        ResourceID = IDR_BUTTONGR;
    }
 
    // Загружаем изображение кнопки из ресурсов приложения
    hbm = LoadBitmap(GetAppHinstance(hwnd), MAKEINTRESOURCE(ResourceID));
 
    // При ошибке ничего не рисуем
    if(!hbm) return;
 
    // Если кнопка выбрана и ее надо целиком
    // перерисовать, вызываем функцию DrawBitmap
    if((lpInfo->itemAction & ODA_DRAWENTIRE) ||
        (lpInfo->itemAction & ODA_SELECT))
    {
        // Рисуем кнопку
        DrawBitmap(lpInfo->hDC,
            (lpInfo->rcItem).left,
            (lpInfo->rcItem).top , hbm);
    }
 
    // Удаляем изображение кнопки, так как оно
    // нам больше не нужно
    DeleteObject(hbm);
}
 
void DrawBitmap(HDC hDC, int x, int y, HBITMAP hBitmap)
{
    HBITMAP hbm, hOldbm;
    HDC hMemDC;
    BITMAP bm;
    POINT ptSize, ptOrg;
 
    // Создаем контекст памяти, совместимый
    // с контекстом отображения
    hMemDC = CreateCompatibleDC(hDC);
 
    // Выбираем изображение bitmap в контекст памяти
    hOldbm = (HBITMAP)SelectObject(hMemDC, hBitmap);
 
    // Если не было ошибок, продолжаем работу
    if (hOldbm)
    {
        // Для контекста памяти устанавливаем тот же
        // режим отображения, что используется в
        // контексте отображения
        SetMapMode(hMemDC, GetMapMode(hDC));
 
        // Определяем размеры изображения
        GetObject(hBitmap, sizeof(BITMAP), (LPSTR) &bm);
 
        ptSize.x = bm.bmWidth;  // ширина
        ptSize.y = bm.bmHeight; // высота
 
        // Преобразуем координаты устройства в логические
        // для устройства вывода
        DPtoLP(hDC, &ptSize, 1);
 
        ptOrg.x = 0;
        ptOrg.y = 0;
 
        // Преобразуем координаты устройства в логические
        // для контекста памяти
        DPtoLP(hMemDC, &ptOrg, 1);
 
        // Рисуем изображение bitmap
        BitBlt(hDC, x, y, ptSize.x, ptSize.y,
            hMemDC, ptOrg.x, ptOrg.y, SRCCOPY);
 
        // Восстанавливаем контекст памяти
        SelectObject(hMemDC, hOldbm);
    }
 
    // Удаляем контекст памяти
    DeleteDC(hMemDC);
}
 
 
int WINAPI WinMain (HINSTANCE hThisInstance,
                    HINSTANCE hPrevInstance,
                    LPSTR lpszArgument,
                    int nFunsterStil)
 
{
    MSG messages;            /* Here messages to the application are saved */
    WNDCLASSEX wincl;        /* Data structure for the windowclass */
    /* The Window structure */
    wincl.hInstance = hThisInstance;
    wincl.lpszClassName = szClassName;
    wincl.lpfnWndProc = WindowProcedure;      /* This function is called by windows */
    wincl.style = CS_DBLCLKS;                 /* Catch double-clicks */
    wincl.cbSize = sizeof (WNDCLASSEX);
    /* Use default icon and mouse-pointer */
    wincl.hIcon = LoadIcon (NULL, IDI_APPLICATION);
    wincl.hIconSm = LoadIcon (NULL, IDI_APPLICATION);
    wincl.hCursor = LoadCursor (NULL, IDC_ARROW);
    wincl.lpszMenuName = NULL;                 /* No menu */
    wincl.cbClsExtra = 0;                      /* No extra bytes after the window class */
    wincl.cbWndExtra = 0;                      /* structure or the window instance */
    /* Use Windows's default color as the background of the window */
    wincl.hbrBackground = (HBRUSH) COLOR_BACKGROUND;
    /* Register the window class, and if it fails quit the program */
    if (!RegisterClassEx (&wincl))
        return 0;
    /* The class is registered, let's create the program*/
    hwnd = CreateWindowEx (
           0,                   /* Extended possibilites for variation */
           szClassName,         /* Classname */
           "Windows App",       /* Title Text */
           WS_OVERLAPPEDWINDOW, /* default window */
           CW_USEDEFAULT,       /* Windows decides the position */
           CW_USEDEFAULT,       /* where the window ends up on the screen */
           544,                 /* The programs width */
           375,                 /* and height in pixels */
           HWND_DESKTOP,        /* The window is a child-window to desktop */
           NULL,                /* No menu */
           hThisInstance,       /* Program Instance handler */
           NULL                 /* No Window Creation data */
           );
 
    hRecord  =  CreateWindow("button", "", WS_CHILD | BS_OWNERDRAW | WS_VISIBLE, 97, 69, 25, 14, hwnd, (HMENU)ID_BUTTON, hThisInstance, NULL);
        80, 25, hwnd, (HMENU)ID_BUTTON, hThisInstance, 0);
    /* Make the window visible on the screen */
    ShowWindow (hwnd, nFunsterStil);
    /* Run the message loop. It will run until GetMessage() returns 0 */
    while (GetMessage (&messages, NULL, 0, 0))
    {
        /* Translate virtual-key messages into character messages */
        TranslateMessage(&messages);
        /* Send message to WindowProcedure */
        DispatchMessage(&messages);
    }
 
    /* The program return-value is 0 - The value that PostQuitMessage() gave */
    return messages.wParam;
}
 
 
/*  This function is called by the Windows function DispatchMessage()  */
 
LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    switch (message)                  /* handle the messages */
    {
        case WM_DRAWITEM :
             DrawButton( (LPDRAWITEMSTRUCT)lParam);
        break;
        case WM_DESTROY:
            PostQuitMessage (0);       /* send a WM_QUIT to the message queue */
            break;
        default:                      /* for messages that we don't deal with */
            return DefWindowProc (hwnd, message, wParam, lParam);
    }
    return 0;
}
вот файл ресурсов

C++
1
2
3
IDR_BUTTONUP                  ICON    DISCARDABLE     "icon.ico"
IDR_BUTTONDOWN                ICON    DISCARDABLE     "icon.ico"
IDR_BUTTONGR                  ICON    DISCARDABLE     "icon.ico"
0
 Аватар для resource2008
111 / 112 / 18
Регистрация: 11.03.2011
Сообщений: 421
13.05.2011, 17:09
на первый взгляд всё нормально.
со 186-й строки "огрызок" функции убрать.

плюс не вижу в коде подключения файла ресурсов. он в каком виде лежит?

Цитата Сообщение от Alex90 Посмотреть сообщение
C++
1
2
// Загружаем изображение кнопки из ресурсов приложения
 hbm = LoadBitmap(GetAppHinstance(hwnd), MAKEINTRESOURCE(ResourceID));
68-я строка, изображение не загружается, поэтому мы ничего и не видим.

да, кстати, сама кнопка отображается (как бы).

позже по свободке внимательней посмотрю - напишу что-то более толковое.
1
23 / 23 / 7
Регистрация: 30.01.2009
Сообщений: 103
18.05.2011, 00:07  [ТС]
а как перерисовать кнопку когда курсор находится над кнопкой?
0
 Аватар для jonson
240 / 213 / 84
Регистрация: 18.03.2010
Сообщений: 750
18.05.2011, 17:57
Цитата Сообщение от Alex90 Посмотреть сообщение
а как перерисовать кнопку когда курсор находится над кнопкой?
примерно так:
в оконной процедуре обрабатывай WM_SETCURSOR.
C++
1
2
3
4
5
6
7
8
9
10
11
case  WM_SETCURSOR:
        if ((HWND)wParam == твоя_OWNERDRAW_кнопка)
            if(GetFocus() != твоя_OWNERDRAW_кнопка)
                SetFocus(твоя_OWNERDRAW_кнопка);
    
                       if ((HWND)wParam != твоя_OWNERDRAW_кнопка)
            if(GetFocus() == твоя_OWNERDRAW_кнопка)
            {
                     // убираешь с неё фокус
            }
           ...
в DrawButton добавляешь
C++
1
2
3
4
5
6
7
8
9
if (lpInfo->itemState & ODS_FOCUS)
{   
     // рисуешь кнопку когда курсор на ней
}
else
{   
     // курсор не на кнопке
}
break;
2
23 / 23 / 7
Регистрация: 30.01.2009
Сообщений: 103
19.05.2011, 02:54  [ТС]
А я вот думал в сторону копать TrackMouseEvent, но тут ступор если
tme.hwndTrack = hwnd; то MessageBox выскакивает, а вот стоить поменять на hRecord или на любой другой то тут молчок. В чем причина?
C++
1
2
3
4
5
6
7
8
9
10
11
12
...
case WM_MOUSEMOVE:
        tme.cbSize      = sizeof(tme);
        tme.dwFlags     = TME_LEAVE;
        tme.dwHoverTime     = HOVER_DEFAULT;
        tme.hwndTrack       = hRecord;
        TrackMouseEvent(&tme);
        break;
    case WM_MOUSELEAVE:
        MessageBox(NULL, "Leave", "", 0);
        break;
...
0
 Аватар для jonson
240 / 213 / 84
Регистрация: 18.03.2010
Сообщений: 750
19.05.2011, 16:20
Вот если что пример OWNERDRAW кнопки.
Не знаю на сколько это правильная реализация, но работает.
Вложения
Тип файла: rar ownerdraw.rar (11.3 Кб, 307 просмотров)
Тип файла: rar project vs2008.rar (941.4 Кб, 263 просмотров)
1
23 / 23 / 7
Регистрация: 30.01.2009
Сообщений: 103
20.05.2011, 21:05  [ТС]
Спасибо за код. Появился баг перестало приходить ODA_SELECT хотя ODA_FOCUS приходит спокойно . С чем это связанно?
0
 Аватар для jonson
240 / 213 / 84
Регистрация: 18.03.2010
Сообщений: 750
20.05.2011, 21:18
Цитата Сообщение от Alex90 Посмотреть сообщение
Появился баг перестало приходить ODA_SELECT
что значит появился? У меня всё работает.
0
23 / 23 / 7
Регистрация: 30.01.2009
Сообщений: 103
21.05.2011, 03:09  [ТС]
До этого я мог обработать два состояние: кнопка без фокуса, кнопка нажата. Теперь же: кнопка без фокуса, кнопка с фокусом уже даже ставил в ODA_SELECT MessageBox он не обрабатывается.
Почему ODA_FOCUS приходит, а вот ODA_SELECT нет (обработчик кнопки работает)?
0
 Аватар для jonson
240 / 213 / 84
Регистрация: 18.03.2010
Сообщений: 750
21.05.2011, 04:30
Цитата Сообщение от Alex90 Посмотреть сообщение
Почему ODA_FOCUS приходит, а вот ODA_SELECT нет
Alex90, выложи сюда свой код, а лучше весь проэкт, или мне в ЛС, хочу посмотреть что не так.
0
23 / 23 / 7
Регистрация: 30.01.2009
Сообщений: 103
21.05.2011, 21:56  [ТС]
Причину кажись нашел. Если подключить манифест тогда выскакивает этот баг
вод код манифеста.

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> 
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<assemblyIdentity 
    version="1.0.0.0"
    processorArchitecture="x86" 
    name="QvasiModo.Programming.FileTypes"
    type="win32"
/>
<description>XP Style</description>
<dependency>
  <dependentAssembly>
    <assemblyIdentity 
         type="win32"
         name="Microsoft.Windows.Common-Controls"
         version="6.0.0.0"
         processorArchitecture="x86"
         publicKeyToken="6595b64144ccf1df"
         language="*"
    />
  </dependentAssembly>
</dependency>
  <trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
    <security>
      <requestedPrivileges>
        <requestedExecutionLevel level='requireAdministrator' uiAccess='false' />
      </requestedPrivileges>
    </security>
  </trustInfo>
</assembly>
Можно как-то использовать стиль ХР, запрос админ прав и что бы приходило и ODA_SELECT?
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
21.05.2011, 21:56
Помогаю со студенческими работами здесь

Разница между стилем css и стилем в коде html
Такой код &lt;html&gt; &lt;head&gt; &lt;meta http-equiv=&quot;content-type&quot; content=&quot;text/html; charset=UTF-8&quot;&gt; &lt;script language = 'javascript'&gt; ...

Непонятный баг (я думаю с BS_OWNERDRAW); выдает ошибку 6(invalid handle)
В общем пишу что-то вроде менеджера загрузок(пока что только окошко к нему). Использую winapi. Все хорошо, создал окошки, кнопочки...

Заморочка с стилем
Всем привет!!! Ребята подскажите как правильно сделать ссылку-картинку. Вот часть кода с файла стилей: /* Menu */ #menu...

Проблемы Со Стилем.
Проблемы со стилем. Перестал работать стиль OneUI при отображении в браузере. В Lotus отображает как положено. В чем может быть...

Qt кнопочка с стилем
Привет! Я хочу добавить к кнопочкам стили. В вебе есть библиотека - bootstrap. Могу ли я как-то стили использовать с этой библиотеки....


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
16
Ответ Создать тему
Новые блоги и статьи
SDL3 для Web (WebAssembly): Работа со звуком через SDL3_mixer
8Observer8 08.02.2026
Содержание блога Пошагово создадим проект для загрузки звукового файла и воспроизведения звука с помощью библиотеки SDL3_mixer. Звук будет воспроизводиться по клику мышки по холсту на Desktop и по. . .
SDL3 для Web (WebAssembly): Основы отладки веб-приложений на SDL3 по USB и Wi-Fi, запущенных в браузере мобильных устройств
8Observer8 07.02.2026
Содержание блога Браузер Chrome имеет средства для отладки мобильных веб-приложений по USB. В этой пошаговой инструкции ограничимся работой с консолью. Вывод в консоль - это часть процесса. . .
SDL3 для Web (WebAssembly): Обработчик клика мыши в браузере ПК и касания экрана в браузере на мобильном устройстве
8Observer8 02.02.2026
Содержание блога Для начала пошагово создадим рабочий пример для подготовки к экспериментам в браузере ПК и в браузере мобильного устройства. Потом напишем обработчик клика мыши и обработчик. . .
Философия технологии
iceja 01.02.2026
На мой взгляд у человека в технических проектах остается роль генерального директора. Все остальное нейронки делают уже лучше человека. Они не могут нести предпринимательские риски, не могут. . .
SDL3 для Web (WebAssembly): Вывод текста со шрифтом TTF с помощью SDL3_ttf
8Observer8 01.02.2026
Содержание блога В этой пошаговой инструкции создадим с нуля веб-приложение, которое выводит текст в окне браузера. Запустим на Android на локальном сервере. Загрузим Release на бесплатный. . .
SDL3 для Web (WebAssembly): Сборка C/C++ проекта из консоли
8Observer8 30.01.2026
Содержание блога Если вы откроете примеры для начинающих на официальном репозитории SDL3 в папке: examples, то вы увидите, что все примеры используют следующие четыре обязательные функции, а. . .
SDL3 для Web (WebAssembly): Установка Emscripten SDK (emsdk) и CMake для сборки C и C++ приложений в Wasm
8Observer8 30.01.2026
Содержание блога Для того чтобы скачать Emscripten SDK (emsdk) необходимо сначало скачать и уставить Git: Install for Windows. Следуйте стандартной процедуре установки Git через установщик. . . .
SDL3 для Android: Подключение Box2D v3, физика и отрисовка коллайдеров
8Observer8 29.01.2026
Содержание блога Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами. Версия v3 была полностью переписана на Си, в. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru