Модераторы: feodorv, GremlinProg, xvr, Fixin
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Не работает SetClassLong(), ..или не приводит к нужному результату 
:(
    Опции темы
S.A.G.
Дата 22.7.2009, 17:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


не эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1339
Регистрация: 20.7.2006
Где: in ad equate

Репутация: нет
Всего: 19



Вот этот вызов

Код
SetClassLong(hwnd, GCL_HBRBACKGROUND, (LONG)CreateSolidBrush(RGB(0, 191, 255)));


в обработчике WM_INITDIALOG, не меняет цвет фона клиентской области. Почему? Функция возвращает 0 и, судя по всему, это не ошибка, а предыдущее значение (GetLastError() и до, и после вызова SetClassLong(), возвращает одну и ту же ошибку, следовательно, функция отрабатывает, но эффекта нет).

Это сообщение отредактировал(а) S.A.G. - 22.7.2009, 17:46


--------------------
Вот она задачка: спасти себя от себя самого © Cube
Sometimes good people do evil things © A Simple Plan
PM   Вверх
GremlinProg
Дата 22.7.2009, 18:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2706
Регистрация: 9.8.2005
Где: Тюмень

Репутация: 99
Всего: 106



SetClassLong модифицирует информацию класса, а не окна
поэтому окно надо дополнительно уведомить об этих изменениях:
Код

::InvalidateRect(hwnd,NULL,TRUE);

Цитата(SetClassLong @ MSDN)

Use the SetClassLong function with care. For example, it is possible to change the background color for a class by using SetClassLong, but this change does not immediately repaint all windows belonging to the class. 



--------------------
"Гений всегда разумнее, чем умнее. Ум — это машина, разум — водитель этой машины."
PM WWW ICQ   Вверх
S.A.G.
Дата 22.7.2009, 18:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


не эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1339
Регистрация: 20.7.2006
Где: in ad equate

Репутация: нет
Всего: 19



GremlinProg, я тоже пристально читал этот текст из MSDN, на что могу ответить.

1. Почему тогда модификация с целью отображения иконки в сис. меню "прокатывает"? 2. Если я затаскиваю окно за границы экрана, сворачиваю, etc., и потом все возвращаю, то почему окно не перерисовывается с использованием новой кисти?

Хотел тебе еще +1 сделать, но какой-то прАтивный скрипт не разрешил.

...

InvalidateRect() НЕ помог. Опасения были. smile

Это сообщение отредактировал(а) S.A.G. - 22.7.2009, 18:46


--------------------
Вот она задачка: спасти себя от себя самого © Cube
Sometimes good people do evil things © A Simple Plan
PM   Вверх
GremlinProg
Дата 22.7.2009, 18:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2706
Регистрация: 9.8.2005
Где: Тюмень

Репутация: 99
Всего: 106



Цитата(S.A.G. @  22.7.2009,  20:27 Найти цитируемый пост)
Почему тогда модификация с целью отображения иконки в сис. меню "прокатывает"?

думаю, в целях оптимизации: чтобы заменить кисть нужно перекрасить автоматом целое окно, которое может даже не использовать эту кисть, а вот заменить иконку - перекрасить очень маленький участок неклиентской области окна

хотя, мое мнение на эту автоматическую перекраску отрицательное:
даже иконку можно не использовать,
просто перехватить NC_PAINT и "не использовать" )
мне бы было не очень комфортно в такой ситуации,
если бы кто-то пытался подумать за меня там, где я уже все продумал
Цитата(S.A.G. @  22.7.2009,  20:27 Найти цитируемый пост)
Если я затаскиваю окно за границы экрана, сворачиваю, etc., и потом все возвращаю, то почему окно не перерисовывается с использованием новой кисти?

может потому что не стоят стили класса: CS_HREDRAW | CS_VREDRAW
или наоборот - стоит стиль CS_SAVEBITS
или у тебя эта кисть просто не используется
причин может быть много,
чтобы найти решающую, надо "смотреть в код"

Цитата(S.A.G. @  22.7.2009,  20:27 Найти цитируемый пост)
Хотел тебе еще +1 сделать, но какой-то прАтивный скрипт не разрешил.

модификация репутации любого участника разрешена только 1 раз в сутки, т.е. раз в 24 часа с момента последней модификации
не переживай, у меня хватает "колышков" )

Добавлено через 5 минут и 58 секунд
Цитата(S.A.G. @  22.7.2009,  20:27 Найти цитируемый пост)
InvalidateRect() НЕ помог. Опасения были. 

самый простой вариан проверить: после смены кисти созать еще один экземпляр этого класса
если ситуация не изменилась, значит одно из двух: либо кисть действительно не используется,
либо кисть не была установлена (неверный дескриптор, к примеру)


--------------------
"Гений всегда разумнее, чем умнее. Ум — это машина, разум — водитель этой машины."
PM WWW ICQ   Вверх
S.A.G.
Дата 22.7.2009, 19:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


не эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1339
Регистрация: 20.7.2006
Где: in ad equate

Репутация: нет
Всего: 19



Цитата(GremlinProg @  22.7.2009,  18:52 Найти цитируемый пост)
чтобы найти решающую, надо "смотреть в код"

Так кода-то нет почти: )

Код

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

BOOL CALLBACK DlgProc(HWND, UINT, WPARAM, LPARAM);
void DlgOnCommand(HWND, int, HWND, UINT);
BOOL DlgOnInitDialog(HWND, HWND, LPARAM);
BOOL OnCtlColorStatic(HWND, HDC, HWND, INT);
void ErrorExit(LPTSTR); //функция из MSDN для обработки ошибок

HINSTANCE hInstance;

int WINAPI WinMain(HINSTANCE hInst, HINSTANCE, LPSTR, int)
{
    hInstance = hInst;
    DialogBox(hInst, MAKEINTRESOURCE(IDD_MAINWND), NULL, DlgProc);

    return 0;
}
BOOL CALLBACK DlgProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
    switch(msg)
    {
        case WM_INITDIALOG:
            return DlgOnInitDialog(hwnd, (HWND)wParam, lParam);

        case WM_COMMAND:
            return (DlgOnCommand(hwnd, (int)LOWORD(wParam), (HWND)lParam,
                    (UINT)HIWORD(wParam)), 0L);

        case WM_CTLCOLORSTATIC:
            return OnCtlColorStatic(hwnd, (HDC)wParam, (HWND)lParam, CTLCOLOR_STATIC);

        default:
            return FALSE;
    }
}
BOOL DlgOnInitDialog(HWND hwnd, HWND, LPARAM)
{
    HFONT hFont;
    HICON hIcon, hIconSm;
    static LOGFONT lf;
    HWND hStatic1, hStatic2, hStatic3;
    static WINDOWINFO StWInfo;
    unsigned uleft, uright, utop, ubottom;
    
    //создание    шрифта, как в редакторе ресурсов, с целью добавления 
    //к ниму атрибута FW_BOLD
    lf.lfHeight = 18;
    lf.lfWeight = FW_BOLD;
    lstrcpy((LPSTR)&lf.lfFaceName, "Arial");
    hFont = CreateFontIndirect(&lf);
    
    //применение созданного шрифта к каждому контролу
    hStatic1 = GetDlgItem(hwnd, IDC_STATIC1);
    hStatic2 = GetDlgItem(hwnd, IDC_STATIC2);
    hStatic3 = GetDlgItem(hwnd, IDC_STATIC3);
    SendMessage(hStatic1, WM_SETFONT, (WPARAM)hFont, TRUE);
    SendMessage(hStatic2, WM_SETFONT, (WPARAM)hFont, TRUE);
    SendMessage(hStatic3, WM_SETFONT, (WPARAM)hFont, TRUE);
    
    StWInfo.cbSize = sizeof(WINDOWINFO);
    
    //сдвигаем IDC_STATIC1 на 1 пиксел вправо
    GetWindowInfo(hStatic1, &StWInfo);
    
    MapWindowPoints(HWND_DESKTOP, hwnd, (POINT *)&StWInfo.rcWindow, 2);
    
    uleft = StWInfo.rcWindow.left; uright = StWInfo.rcWindow.right;
    utop = StWInfo.rcWindow.top; ubottom = StWInfo.rcWindow.bottom;
    SetWindowPos(hStatic1, 0, uleft + 1, utop, 0, 0, SWP_NOZORDER | SWP_NOSIZE);
    
    //сдвигаем IDC_STATIC3 на 1 пиксел влево
    GetWindowInfo(hStatic3, &StWInfo);
    
    MapWindowPoints(HWND_DESKTOP, hwnd, (POINT *)&StWInfo.rcWindow, 2);
    
    uleft = StWInfo.rcWindow.left; uright = StWInfo.rcWindow.right;
    utop = StWInfo.rcWindow.top; ubottom = StWInfo.rcWindow.bottom;
    SetWindowPos(hStatic3, 0, uleft - 1, utop, 0, 0, SWP_NOZORDER | SWP_NOSIZE);
    
    //загрузка стандартной и малой пиктограмм
    hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_IPF_ICO));
    hIconSm = (HICON)LoadImage(hInstance, MAKEINTRESOURCE(IDI_IPF_ICO), 
                               IMAGE_ICON, 16, 16, LR_DEFAULTCOLOR);
    SetClassLong(hwnd, GCL_HICON, (LONG)hIcon);
    SetClassLong(hwnd, GCL_HICONSM, (LONG)hIconSm);

    SetClassLong(hwnd, GCL_HBRBACKGROUND, 
                 (LONG)CreateSolidBrush(RGB(0, 191, 255)));

    return TRUE;
}
void DlgOnCommand(HWND hwnd, int id, HWND, UINT)
{
    switch(id)
    {
        case IDCANCEL:
            EndDialog(hwnd, 0);
    }
}
BOOL OnCtlColorStatic(HWND, HDC hDC, HWND hwnd, INT)
{
    int id = GetDlgCtrlID(hwnd);
        switch(id)
        {
            case IDC_STATIC1:
                SetBkColor(hDC, RGB(0, 169, 0));
                break;
            
            case IDC_STATIC2:
                SetBkColor(hDC, RGB(0, 189, 0));
                break;

            case IDC_STATIC3:
                SetBkColor(hDC, RGB(0, 209, 0));
                break;

            default:
                return FALSE;
        }
    return (BOOL)(UINT_PTR)GetStockObject(NULL_BRUSH);
}
void ErrorExit(LPTSTR lpszFunction)
{ 
    // Retrieve the system error message for the last-error code

    LPVOID lpMsgBuf;
    LPVOID lpDisplayBuf;
    DWORD dw = GetLastError(); 

    FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM |
                  FORMAT_MESSAGE_IGNORE_INSERTS, NULL, dw,
                  MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) &lpMsgBuf,
                  0, NULL );

    // Display the error message and exit the process

    lpDisplayBuf = (LPVOID)LocalAlloc(LMEM_ZEROINIT, 
        (lstrlen((LPCTSTR)lpMsgBuf)+lstrlen((LPCTSTR)lpszFunction)+40)*sizeof(TCHAR)); 

    StringCchPrintf((LPTSTR)lpDisplayBuf, LocalSize(lpDisplayBuf) / sizeof(TCHAR),
                    TEXT("%s failed with error %d: %s"), lpszFunction, dw, lpMsgBuf); 
    
    MessageBox(NULL, (LPCTSTR)lpDisplayBuf, TEXT("Error"), MB_OK); 

    LocalFree(lpMsgBuf);
    LocalFree(lpDisplayBuf);
    ExitProcess(dw);
}


Последняя функция из MSDN.

Код

// Microsoft Visual C++ generated resource script.
//
#include "resource.h"

#define APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 2 resource.
//
#include "afxres.h"

/////////////////////////////////////////////////////////////////////////////
#undef APSTUDIO_READONLY_SYMBOLS

/////////////////////////////////////////////////////////////////////////////
// украинский resources

#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_UKR)
#ifdef _WIN32
LANGUAGE LANG_UKRAINIAN, SUBLANG_DEFAULT
#pragma code_page(1251)
#endif //_WIN32

#ifdef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// TEXTINCLUDE
//

1 TEXTINCLUDE 
BEGIN
    "resource.h\0"
END

2 TEXTINCLUDE 
BEGIN
    "#include ""afxres.h""\r\n"
    "\0"
END

3 TEXTINCLUDE 
BEGIN
    "\r\n"
    "\0"
END

#endif    // APSTUDIO_INVOKED


/////////////////////////////////////////////////////////////////////////////
//
// Dialog
//

IDD_MAINWND DIALOGEX 0, 0, 160, 40
STYLE DS_SETFONT | DS_MODALFRAME | DS_CENTER | WS_MINIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "IPFormatter"
FONT 12, "Arial", 700, 0, 0xCC
BEGIN
    LTEXT           " Открыть ",IDC_STATIC1,18,16,32,8
    LTEXT           " Преобразовать ",IDC_STATIC2,50,16,54,8
    LTEXT           " Сохранить ",IDC_STATIC3,104,16,39,8
END


/////////////////////////////////////////////////////////////////////////////
//
// DESIGNINFO
//

#ifdef APSTUDIO_INVOKED
GUIDELINES DESIGNINFO 
BEGIN
    IDD_MAINWND, DIALOG
    BEGIN
        LEFTMARGIN, 7
        TOPMARGIN, 7
    END
END
#endif    // APSTUDIO_INVOKED


/////////////////////////////////////////////////////////////////////////////
//
// Icon
//

// Icon with lowest ID value placed first to ensure application icon
// remains consistent on all systems.
IDI_IPF_ICO             ICON                    "icon.ico"
#endif    // украинский resources
/////////////////////////////////////////////////////////////////////////////



#ifndef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 3 resource.
//


/////////////////////////////////////////////////////////////////////////////
#endif    // not APSTUDIO_INVOKED



--------------------
Вот она задачка: спасти себя от себя самого © Cube
Sometimes good people do evil things © A Simple Plan
PM   Вверх
GremlinProg
Дата 22.7.2009, 19:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2706
Регистрация: 9.8.2005
Где: Тюмень

Репутация: 99
Всего: 106



ага, вот оно что, )
ты пытаешься сменить кисть у диалога
так ведь это глобальный класс,
он эту кисть вообще не использует, GetClassInfo для него вернется с нулевой кистью изначально

вообще, большинство стандартных классов не используют кисть класса
они используют прямые системные цвета и кисти из GetSysColor, GetSysColorBrush с параметрами COLOR_WINDOW, COLOR_BTNFACE и т.п.

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


--------------------
"Гений всегда разумнее, чем умнее. Ум — это машина, разум — водитель этой машины."
PM WWW ICQ   Вверх
S.A.G.
Дата 22.7.2009, 19:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


не эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1339
Регистрация: 20.7.2006
Где: in ad equate

Репутация: нет
Всего: 19



Цитата(GremlinProg @  22.7.2009,  19:23 Найти цитируемый пост)
ага, вот оно что

Так ты ж раньше знал, что дело было с диалогом. Невнимательный, оказывается, не только я. smile
Цитата(GremlinProg @  22.7.2009,  19:23 Найти цитируемый пост)
ты пытаешься сменить кисть у диалога

Ога
Цитата(GremlinProg @  22.7.2009,  19:23 Найти цитируемый пост)
так ведь это глобальный класс,

М-да, интересно, через сколько дней я бы нашел у себя такую очевидную ошибку..? А что же такое "глобальный класс"? Плиз, ссылку на MSDN с классификацией классов.
Цитата(GremlinProg @  22.7.2009,  19:23 Найти цитируемый пост)
он эту кисть вообще не использует

Нафег она тогда там? Вернула бы SetClassLong() ошибку, и да расшифровал бы я ее с помощью GetLastError(), и поведала бы она мне, что я пихаю свой бруш не туда, так нет - в Windows программисту "не мешают", как и в C++..
Цитата(GremlinProg @  22.7.2009,  19:23 Найти цитируемый пост)
в диалоге менять фон можно либо вручную, при прорисовке

Купить гуашь, кисточку и красить по экрану? Какой месэдж обрабатывать?


--------------------
Вот она задачка: спасти себя от себя самого © Cube
Sometimes good people do evil things © A Simple Plan
PM   Вверх
GremlinProg
Дата 22.7.2009, 20:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2706
Регистрация: 9.8.2005
Где: Тюмень

Репутация: 99
Всего: 106



не кипятись, я же не телепат, чтобы связать шрифт и кисть в одну логическую цепочку
Цитата(S.A.G. @  22.7.2009,  21:43 Найти цитируемый пост)
М-да, интересно, через сколько дней я бы нашел у себя такую очевидную ошибку..? А что же такое "глобальный класс"? Плиз, ссылку на MSDN с классификацией классов.

http://msdn.microsoft.com/en-us/library/ms...85).aspx#system
Цитата(S.A.G. @  22.7.2009,  21:43 Найти цитируемый пост)
Нафег она тогда там? Вернула бы SetClassLong() ошибку, и да расшифровал бы я ее с помощью GetLastError(), и поведала бы она мне, что я пихаю свой бруш не туда, так нет - в Windows программисту "не мешают", как и в C++..

она там для заказных, пользовательских классов
а ошибку при всем желании вернуть нельзя, т.к. эта установки кисти не фильтруется ни какими обработчиками
кисть в классе окна - это просто место, в которое можно посмотреть, а можно и не смотреть,
жесткой привязки ее назначения нет, ты можешь эту кисть использовать не для всего окна,
а к примеру только для вывода текста, или какой-то небольшой области окна,
все решает тот, кто программирует процедуру окна, а в данном случае - это не ты,
хотя свой вклад можешь вносить по-прежнему, через диалоговую процедуру, но это уже вторичный вклад
Цитата(S.A.G. @  22.7.2009,  21:43 Найти цитируемый пост)
Купить гуашь, кисточку и красить по экрану? Какой месэдж обрабатывать?

обычно WM_PAINT


--------------------
"Гений всегда разумнее, чем умнее. Ум — это машина, разум — водитель этой машины."
PM WWW ICQ   Вверх
S.A.G.
Дата 22.7.2009, 20:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


не эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1339
Регистрация: 20.7.2006
Где: in ad equate

Репутация: нет
Всего: 19



Цитата(GremlinProg @  22.7.2009,  20:02 Найти цитируемый пост)
обычно WM_PAINT

Что вызвать в обработчике?


--------------------
Вот она задачка: спасти себя от себя самого © Cube
Sometimes good people do evil things © A Simple Plan
PM   Вверх
GremlinProg
Дата 22.7.2009, 20:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2706
Регистрация: 9.8.2005
Где: Тюмень

Репутация: 99
Всего: 106



Код

PAINTSTRUCT ps;
::BeginPaint( hwnd, &ps );
hBrush = ::CreateSolidBrush( RGB( 255, 0, 0 ) );
::FillRect( ps.hdc, &ps.rcPaint, hBrush );
::EndPaint( hwnd, &ps );

все это, и много чего еще, можно найти в примерах, особенно, если искать: http://forum.vingrad.ru/act-Search/CODE/sh...kgnd/index.html

9 страниц - не 100,
запрос можно уточнять
дополняй запрос ключевыми словами, будет еще меньше


--------------------
"Гений всегда разумнее, чем умнее. Ум — это машина, разум — водитель этой машины."
PM WWW ICQ   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "C/C++: Системное программирование и WinAPI"
Fixin
GremlinProg
xvr
feodorv
  • Большое количество информации и примеров с использованием функций WinAPI можно найти в MSDN
  • Описание сообщений, уведомлений и примеров с использованием компонент WinAPI (BUTTON, EDIT, STATIC, и т.п.), можно найти в MSDN Control Library
  • Непосредственно, перед созданием новой темы, проверьте заголовок и удостоверьтесь, что он отражает суть обсуждения.
  • После заполнения поля "Название темы", обратите внимание на наличие и содержание панели "А здесь смотрели?", возможно Ваш вопрос уже был решен.
  • Приводите часть кода, в которой предположительно находится проблема или ошибка.
  • Если указываете код, пользуйтесь тегами [code][/code], или их кнопочными аналогами.
  • Если вопрос решен, воспользуйтесь соответствующей ссылкой, расположенной напротив названия темы.
  • Один топик - один вопрос!
  • Перед тем как создать тему - прочтите это .

На данный раздел распространяются Правила форума и Правила раздела С++:Общие вопросы .


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Chipset, Step, Fixin, GremlinProg, xvr. feodorv.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Системное программирование и WinAPI | Следующая тема »


 




[ Время генерации скрипта: 0.1021 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.