Форум программистов, компьютерный форум, киберфорум
C/C++: WinAPI
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 5.00/9: Рейтинг темы: голосов - 9, средняя оценка - 5.00
0 / 0 / 0
Регистрация: 10.12.2012
Сообщений: 6

Не отображает кнопки в рабочей области

24.12.2013, 03:54. Показов 1836. Ответов 11
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Доброго времени суток, уважаемые специалисты. Столкнулся с проблемой, которую нахожу по всему сайту, но решается она у всех каким-то магическим образом: создаю Button, который даже выполняет событие, но абсолютно не под какими предлогами не хочет отображаться(создаваемое родительское окно задается поверх всех запущенных + строится по маске изображения)

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
#include <windows.h>
#include <gdiplus.h>
 
using namespace Gdiplus;
 
#include <shlwapi.h>
 
#ifdef UNICODE
 
#ifndef _UNICODE
#define _UNICODE
#endif
 
#endif
#include <tchar.h>
 
#include "main.h"
 
TCHAR lpWindowClass[] = _T("PNGFormWndClass");
TCHAR lpWindowTitle[] = _T("'PNG form' sample");
 
#ifdef _DEBUG
TCHAR lpPNGMaskFileName[] = _T("Debug\\dedm.png");
#else
TCHAR lpPNGMaskFileName[] = _T("dedm.png");
#endif
 
ULONG_PTR gdipToken;
GdiplusStartupInput gdipStartupInput;
Image *pPNGMask = NULL;
Graphics *pGraphics = NULL;
HINSTANCE hInst;
int APIENTRY _tWinMain(HINSTANCE hInstance,
                     HINSTANCE hPrevInstance,
                     LPTSTR    lpCmdLine,
                     int       nCmdShow)
{
    MSG msg;
    static HWND hButton, hListBox, hComboBox;
    PAINTSTRUCT ps;
    WNDCLASSEX wcex={};
    HWND hWnd;
    HDC hdc;
    wcex.cbSize = sizeof(WNDCLASSEX);
    wcex.style = CS_HREDRAW | CS_VREDRAW;
    wcex.lpfnWndProc = WndProc;
    wcex.hInstance = hInstance;
    wcex.hIcon = LoadIcon(hInstance, IDI_APPLICATION);
    wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
    wcex.hbrBackground = GetSysColorBrush(COLOR_BTNFACE);
    wcex.lpszClassName = lpWindowClass;
    wcex.hIconSm = LoadIcon(wcex.hInstance, IDI_APPLICATION);
 
    if (!RegisterClassEx(&wcex))
        return FALSE;
 
    //Инициализируем GDI+
    GdiplusStartup(&gdipToken, &gdipStartupInput, NULL);
 
    //Проверяем наличие файла маски
    if (!PathFileExists(lpPNGMaskFileName))
    {
        TCHAR lpMsg[512] = {};
        _stprintf(lpMsg, _T("Отсутствует файл маски '%s'!"), lpPNGMaskFileName);
        MessageBox(NULL, lpMsg, NULL, MB_ICONEXCLAMATION);
        return FALSE;
    }
 
    //Создаем объект Image на основе файла.
    pPNGMask = new Image(lpPNGMaskFileName);
    hInst = hInstance;
    HWND hWndDesktop = GetDesktopWindow();
    hWnd = CreateWindowEx(WS_EX_LAYERED | WS_EX_TOPMOST | WS_EX_TOOLWINDOW, lpWindowClass, lpWindowTitle, WS_POPUP, CW_USEDEFAULT, CW_USEDEFAULT, pPNGMask->GetWidth(),
        pPNGMask->GetHeight(), hWndDesktop, NULL, hInstance, NULL);
    hButton = CreateWindow(
        L"BUTTON", 
        L"Class Options", 
        WS_VISIBLE | WS_CHILD| BS_PUSHBUTTON,  50, 55, 200, 30, hWnd, (HMENU)100, hInst, 0);
    if (hWnd)
    {
        ShowWindow(hWnd, nCmdShow);
        UpdateWindow(hWnd);
 
        while (GetMessage(&msg, NULL, 0, 0))
        {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
    }
    
    if (pPNGMask)
        delete pPNGMask;
    if (pGraphics)
        delete pGraphics;
 
    return (int)msg.wParam;
}
 
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    static HWND hButton, hListBox, hComboBox;
    switch (message)
    {
        case WM_CREATE:
        {
            BITMAPINFO BMI = {};
            BLENDFUNCTION BF = {};
            POINT ptDst = {GetSystemMetrics(SM_CXSCREEN)/2, GetSystemMetrics(SM_CYSCREEN)/2}, ptSrc = {0, 0};
            SIZE szDst = {pPNGMask->GetWidth(), pPNGMask->GetHeight()};
            
            //Инициализируем составляющие временного DC, в который будет отрисована маска
            auto hDC = GetDC(hWnd);
            auto hCDC = CreateCompatibleDC(hDC);
            BMI.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
            BMI.bmiHeader.biBitCount = 32;
            BMI.bmiHeader.biCompression = BI_RGB;
            BMI.bmiHeader.biWidth = pPNGMask->GetWidth();
            BMI.bmiHeader.biHeight = pPNGMask->GetHeight();
            BMI.bmiHeader.biPlanes = 1;
            auto h32bppBitmap = CreateDIBSection(hDC, &BMI, DIB_RGB_COLORS, NULL, NULL, 0);
            
            SelectObject(hCDC, h32bppBitmap);
            //Создаем объект Graphics на основе контекста окна
            pGraphics = new Graphics(hCDC);
            //Рисуем маску на окне
            pGraphics->DrawImage(pPNGMask, 0, 0, pPNGMask->GetWidth(), pPNGMask->GetHeight());
            //В параметрах ULW определяем, что в качестве значения полупрозрачности будет использоваться
            //альфа-компонент пикселей исходного изображения
            BF.AlphaFormat = AC_SRC_ALPHA;
            BF.BlendOp = AC_SRC_OVER;
            BF.SourceConstantAlpha = 255;
                        //Применяем отрисованную маску с альфой к окну
            UpdateLayeredWindow(hWnd, hDC, &ptDst, &szDst, hCDC, &ptSrc, 0, &BF, ULW_ALPHA);
            
            DeleteObject(h32bppBitmap);
            DeleteDC(hCDC);
            ReleaseDC(hWnd, hDC);
            hButton = CreateWindow (L"BUTTON",L"Button", WS_CHILD | WS_VISIBLE| BS_DEFPUSHBUTTON,
                                    10, 0, 119, 20, hWnd, (HMENU)100, hInst, NULL);
            break;
        }
        case WM_COMMAND:
        switch (LOWORD(wParam))
        {
        case 100:
            {
                MessageBox (hWnd, L"Button", L"", 0);
            }
        }
        break;
        case WM_LBUTTONDOWN:
            ReleaseCapture();
            SendMessage(hWnd, WM_NCLBUTTONDOWN, HTCAPTION, 0);
            break;
        /*case WM_KEYUP:
            if (wParam == VK_ESCAPE)
                DestroyWindow(hWnd);
            break;*/
        case WM_DESTROY:
            PostQuitMessage(0);
            break;
        default:
            return DefWindowProc(hWnd, message, wParam, lParam);
    }
 
    return 0;
}
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
24.12.2013, 03:54
Ответы с готовыми решениями:

Действия при нажатии левой(правой) кнопки мыши в рабочей области окна
Нужно Написать Win32API. Что бы правая и левая кнопка мыши выполняли действия написанные в варианте! Помогите пожалуйста.

Создание кнопки в рабочей области
Начал работу с Qt. Использую VS 2010. Как в главном окне программы создать обычную кнопку, чтобы при её нажатии передавалась текстовая...

Кнопки выходят за пределы рабочей области, Bootstrap
остается загадкой одно)) кнопки выходят за пределы рабочей области.... &lt;!DOCTYPE html&gt; &lt;html lang=&quot;en&quot;&gt; ...

11
Заблокирован
24.12.2013, 05:05
Вы пытаетесь создать окно с прозрачным фоном а-ля Aero и разместить на нём стандартные контролы?
Не получится, рисуйте свои. Или откажитесь от свистоперделок вовсе (сомневаюсь, что это так уж тяжело).
(Завтра попробую посмотреть, но вряд ли что выйдет - ни одного рабочего решения я не видел, хотя сам в своё время искал.)

Если Вам нужно просто нарисовать PNG на окне, то уберите UpdateLayeredWindow() и BLENDFUNCTION и просто рисуйте изображение прямо на HDC.
0
0 / 0 / 0
Регистрация: 10.12.2012
Сообщений: 6
24.12.2013, 13:51  [ТС]
Цитата Сообщение от Водяной Змей Посмотреть сообщение
Вы пытаетесь создать окно с прозрачным фоном а-ля Aero и разместить на нём стандартные контролы?
Не получится, рисуйте свои. Или откажитесь от свистоперделок вовсе (сомневаюсь, что это так уж тяжело).
(Завтра попробую посмотреть, но вряд ли что выйдет - ни одного рабочего решения я не видел, хотя сам в своё время искал.)

Если Вам нужно просто нарисовать PNG на окне, то уберите UpdateLayeredWindow() и BLENDFUNCTION и просто рисуйте изображение прямо на HDC.
Не совсем понял, что подразумевается под Aero, если это про виндоус стиль, то у них полупрозрачность. Ну, это так) А вообще отказаться от масок и смешивания я не могу, потому как программа именно что должна создавать окно формы изображения.

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

Добавлено через 43 минуты
Не знаю, как обновить предыдущий пост и направить его Водяному Змею(кто может, объясните на будущее), но ваш ответ про окна Aero и впрямь оказался полезным. По крайней мере теперь я нашел конфликт. Действительно окна Aero вроде как создаются при помощи свойства Layered и если убрать слоистость окна, то элемент управления появляется. Однако пока остается вопросом, возможно ли при наличии слоистого окна добавить окно потомка, потому что кроме этого метода, если честно не знаю как сотворить окно формы битмапы

оффтоп: а вот оно что, сообщение само по себе приклеивается к предыдущему=)
0
Заблокирован
24.12.2013, 14:35
возможно ли при наличии слоистого окна добавить окно потомка, потому что кроме этого метода, если честно не знаю как сотворить окно формы битмапы
А перетаскивание с растягиванием? Будут отставать друг от друга, разве что прицепить как-нибудь низкоуровнево.

По идее, есть способ получше.
Есть такая штука, как Winforms. Это из дотнета.
Там нечто подобное можно сделать, если перехватить событие отрисовки фона окна и в нём средствами GDI+ рисовать картинку.
Тогда стандартные контролы размещаются нормально. (С CreateWindow() не пробовал, но, думаю, тоже сработает).
Только там надо ещё окну регион задать, чтобы прозрачные точки исключить и по ним можно было кликать мышкой, как по более нижним окнам или рабочему столу. Его можно создать самому, просканировав картинку на предмет таких точек. Хотя если окно несложной формы, то можно и без этого обойтись - никто и не заметит, что там мышка не кликает.

Добавлено через 2 минуты
Действительно окна Aero вроде как создаются при помощи свойства Layered
Там всё сложнее.
Там DirectX. Может, если и Вы изучите DirectX и примените в своём примере, то тоже прокатит - он посильнее, чем GDI+.
0
0 / 0 / 0
Регистрация: 10.12.2012
Сообщений: 6
24.12.2013, 15:31  [ТС]
Цитата Сообщение от Водяной Змей Посмотреть сообщение
А перетаскивание с растягиванием? Будут отставать друг от друга, разве что прицепить как-нибудь низкоуровнево.

По идее, есть способ получше.
Есть такая штука, как Winforms. Это из дотнета.
Там нечто подобное можно сделать, если перехватить событие отрисовки фона окна и в нём средствами GDI+ рисовать картинку.
Тогда стандартные контролы размещаются нормально. (С CreateWindow() не пробовал, но, думаю, тоже сработает).
Только там надо ещё окну регион задать, чтобы прозрачные точки исключить и по ним можно было кликать мышкой, как по более нижним окнам или рабочему столу. Его можно создать самому, просканировав картинку на предмет таких точек. Хотя если окно несложной формы, то можно и без этого обойтись - никто и не заметит, что там мышка не кликает.

Добавлено через 2 минуты

Там всё сложнее.
Там DirectX. Может, если и Вы изучите DirectX и примените в своём примере, то тоже прокатит - он посильнее, чем GDI+.
Эмммм, я бы с радостью формочками попользовался, если 12-я студия с ними работала. Или я неправильно понял вас?

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

А на счет директа.. Изучить то было бы пожалуй не лишним, но вряд ли пока ради новогодней минипрограммки оно нужно)

Добавлено через 14 минут
А если поверх отрисовать еще одно прозрачное окно, оно опять же из-за прозрачности кнопки не будет отображать?
0
Заблокирован
24.12.2013, 17:19
Эмммм, я бы с радостью формочками попользовался, если 12-я студия с ними работала. Или я неправильно понял вас?
1) Работает она с ними. Здесь почитайте.
2) Лучше C# учите для формочек, он не сложнее, но куда востребованнее у заказчиков.

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

Изучить то было бы пожалуй не лишним, но вряд ли пока ради новогодней минипрограммки оно нужно)
Тогда проще нарисовать все контролы свои.
Ведь так даже оригинальнее. И GDI+ глубже изучите.
1
Эксперт С++
4986 / 3093 / 456
Регистрация: 10.11.2010
Сообщений: 11,170
Записей в блоге: 10
24.12.2013, 19:23
Почитай про Layered Windows. С ними как с обычными окнами работать нельзя.
0
0 / 0 / 0
Регистрация: 10.12.2012
Сообщений: 6
25.12.2013, 00:56  [ТС]
Цитата Сообщение от Водяной Змей Посмотреть сообщение
Тогда проще нарисовать все контролы свои.
Ведь так даже оригинальнее. И GDI+ глубже изучите
Спасибо, реализовал через добавление второго окна, на которое и запихал все элементы управления. Правда возник еще один вопрос: в общем, у первого окна, которое Layered, заблочино перемещение мышкой( тут все как надо), но столкнулся с трудностью сделать это со вторым. Перемещение окна именно, что не нужно, а если второе будет перетаскиваемым, то выглядеть будет довольно глупо
Бороздил просторы интернета и нашел несколько вариантов запрета перемещения окна, но почему то оба не дают ровным счетом никакого эффекта:
Первый
C++
1
2
3
4
5
6
7
8
case WM_SHOWWINDOW:
        static RECT r;
        GetWindowRect(hWnd,&r);
        break;
    case WM_MOVING:
        *((RECT*)lParam)=r;
        return DefWindowProc(hWnd, message, wParam, lParam);
        break;
Здесь по идее должны при перемещении сохраненные координаты заменять новые, но этого соответственно не происходит
Второй
C++
1
2
3
4
5
6
7
case WM_NCHITTEST:
{
    LRESULT lRes = DefWindowProc(hWnd, WM_NCHITTEST, wParam, lParam);
    if (lRes == HTCAPTION)
        lRes = HTCLIENT;
    return lRes;
}
Тут как я понял, цепляется мышиное сообщение WM_NCHITTEST и заменяется тут же при попытке входа в цикл обработки перетаскивания, но опять же это не помогло.
В связи со всем этим, может сможете помочь защитить окно от мыши?)
Цитата Сообщение от castaway Посмотреть сообщение
Почитай про Layered Windows. С ними как с обычными окнами работать нельзя.
Благодарю, уже почитал, осознал и как написал выше выкрутился из ситуации =)
0
Заблокирован
25.12.2013, 02:18
защитить окно от мыши
Может просто все окна без рамок сделать (WS_POPUP)?
Тогда ничего само по себе перемещаться не будет, только если Вы запрограммируете.
0
0 / 0 / 0
Регистрация: 10.12.2012
Сообщений: 6
25.12.2013, 02:58  [ТС]
Цитата Сообщение от Водяной Змей Посмотреть сообщение
Может просто все окна без рамок сделать (WS_POPUP)?
Тогда ничего само по себе перемещаться не будет, только если Вы запрограммируете.
Оба окна POPUP итак идут, а перемещает он второе окно за любую из частей окна
0
Заблокирован
25.12.2013, 03:06
Оба окна POPUP итак идут, а перемещает он второе окно за любую из частей окна
Получайте координаты мыши и посылайте сообщение перемещаться только при определённых значениях координат.
0
0 / 0 / 0
Регистрация: 10.12.2012
Сообщений: 6
25.12.2013, 11:02  [ТС]
Цитата Сообщение от Водяной Змей Посмотреть сообщение
Получайте координаты мыши и посылайте сообщение перемещаться только при определённых значениях координат.
Еще раз спасибо за помощь, в итоге помог тот метод который описывал выше, где подменял мышиное сообщение с новыми координатами сохраненными. Проблема была моей личной невнимательности при создании второго окна(обработчик второго окна попросту не запускался и, если честно был вообще не нуужен, одного обработчика было достаточно. как вы понимаете, обработку перетаскивания я запихивал именно в функцию для второго окна)
В целом, закончил программу с парочкой маленьких косяков : фон статика с текстом почему-то не могу обнулить:
C++
1
2
3
4
5
6
7
8
9
case WM_CTLCOLORSTATIC:
    {
        if(text==(HWND)lParam)
        {
            HDC hdcStatic = (HDC)wParam;
            SetTextColor(hdcStatic, 0x0);
            SetBkMode((HDC)wParam, TRANSPARENT);
            GetStockObject(NULL_BRUSH);
        }
и у программы есть такой момент, когда надо удалить кнопку DestroyWindow(prev);, что изначально прекрасно срабатывало, а в какой-то момент перестало и теперь когда доходит до удаления - кнопка остается, но на нее нельзя нажать. Может окно отчего то не перерисовывается?
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
25.12.2013, 11:02
Помогаю со студенческими работами здесь

В рабочей области отображена надпись "Нажмите правую клавишу мыши над рабочей областью"
Здравствуйте, нужна помощь с заданием. В рабочей области отображена надпись &quot;Нажмите правую клавишу мыши над рабочей...

Перезапуск рабочей области
Имеется вот такая форма (полный код приложен в архиве), я только пару дней работаю с графическими оболочками и в частности ВинФормс,...

Деление рабочей области
Здравствуйте! Подскажите пожалуйста как или при помощи каких функций можно разделить рабочую область окна на 3. Чтобы Деление проходило по...

Разделение рабочей области
Доброго времени суток! К компьютеру подключена видеостена, состоящая из 9 экранов. Возникла необходимость разделить рабочий экран на 9...

Интерфейс рабочей области
Здравствуйте! Как сделать такие вкладки на 1С 8.2? И как задавать наименования таким вкладкам?


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

Или воспользуйтесь поиском по форуму:
12
Ответ Создать тему
Новые блоги и статьи
SDL3 для Web (WebAssembly): сборка C/C++ проекта из консоли
8Observer8 30.01.2026
Содержание блога Если вы откроете примеры для начинающих на официальном репозитории SDL3 в папке: examples, то вы увидите, что все примеры используют следующие четыре обязательные функции, а. . .
Установка Emscripten SDK (emsdk) и CMake на Windows для сборки C и C++ приложений в WebAssembly (Wasm)
8Observer8 30.01.2026
Чтобы скачать Emscripten SDK (emsdk) необходимо сначало скачать и уставить Git: Install for Windows. Следуйте стандартной процедуре установки Git через установщик. Система контроля версиями Git. . .
Подключение Box2D v3 к SDL3 для Android: физика и отрисовка коллайдеров
8Observer8 29.01.2026
Содержание блога Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами. Версия v3 была полностью переписана на Си, в. . .
Инструменты COM: Сохранение данный из VARIANT в файл и загрузка из файла в VARIANT
bedvit 28.01.2026
Сохранение базовых типов COM и массивов (одномерных или двухмерных) любой вложенности (деревья) в файл, с возможностью выбора алгоритмов сжатия и шифрования. Часть библиотеки BedvitCOM Использованы. . .
Загрузка PNG с альфа-каналом на SDL3 для Android: с помощью SDL_LoadPNG (без SDL3_image)
8Observer8 28.01.2026
Содержание блога SDL3 имеет собственные средства для загрузки и отображения PNG-файлов с альфа-каналом и базовой работы с ними. В этой инструкции используется функция SDL_LoadPNG(), которая. . .
Загрузка PNG с альфа-каналом на SDL3 для Android: с помощью SDL3_image
8Observer8 27.01.2026
Содержание блога SDL3_image - это библиотека для загрузки и работы с изображениями. Эта пошаговая инструкция покажет, как загрузить и вывести на экран смартфона картинку с альфа-каналом, то есть с. . .
Влияние грибов на сукцессию
anaschu 26.01.2026
Бифуркационные изменения массы гриба происходят тогда, когда мы уменьшаем массу компоста в 10 раз, а скорость прироста биомассы уменьшаем в три раза. Скорость прироста биомассы может уменьшаться за. . .
Воспроизведение звукового файла с помощью SDL3_mixer при касании экрана Android
8Observer8 26.01.2026
Содержание блога SDL3_mixer - это библиотека я для воспроизведения аудио. В отличие от инструкции по добавлению текста код по проигрыванию звука уже содержится в шаблоне примера. Нужно только. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru