Alt+Tab + своя миниатюра окна
От: Carc Россия https://vk.com/gosha_mazov
Дата: 01.03.23 09:22
Оценка:
Откуда Windows берет миниатюру окна, которая показывается в списке окон по Alt+Tab?

Про DWM-api я в курсе.
Но даже если окно ничего не делает с DWM (старые приложение, кои про DWM не в курсе), то Винда явно же откуда-то копирует изображение окна?

Ну кагбэ понятно, что Винда тягает бекграунд клиентской области...
Но когда? В какой момент?

Я вроть в WM_ERASEBKGNG нарисосвал какую-то "порнуху" на фоне окошка... Но Винда его таки ее не показывает. Просто пустую клиентскую область (коя там и есть).
Ощущение, что миниатюра запрашивается раньше, чем я "художничаю" в WM_ERASEBKGND\WM_PAINT.

Куда копать?
Aml Pages Home
Re: Alt+Tab + своя миниатюра окна
От: qaz77  
Дата: 01.03.23 09:31
Оценка:
Здравствуйте, Carc, Вы писали:

C>Откуда Windows берет миниатюру окна, которая показывается в списке окон по Alt+Tab?


Может через WM_PRINTCLIENT?
Re: Alt+Tab + своя миниатюра окна
От: ononim  
Дата: 01.03.23 09:31
Оценка:
C>Куда копать?
нынче окна всегда рисуются в offscreen, а когда надо его нарисовать кудато — на десктопе или в миниатюру — композитный менеджер копирует контент из offscreen картинки окна
https://ru.wikipedia.org/wiki/%D0%9A%D0%BE%D0%BC%D0%BF%D0%BE%D0%B7%D0%B8%D1%82%D0%BD%D1%8B%D0%B9_%D0%BC%D0%B5%D0%BD%D0%B5%D0%B4%D0%B6%D0%B5%D1%80_%D0%BE%D0%BA%D0%BE%D0%BD
Как много веселых ребят, и все делают велосипед...
Re[2]: Alt+Tab + своя миниатюра окна
От: Carc Россия https://vk.com/gosha_mazov
Дата: 01.03.23 11:07
Оценка:
Здравствуйте, qaz77, Вы писали:

Q>Здравствуйте, Carc, Вы писали:


C>>Откуда Windows берет миниатюру окна, которая показывается в списке окон по Alt+Tab?


Q>Может через WM_PRINTCLIENT?

Не приходят в оконную процедуру, ни WM_PRINTCLIENT, ни WM_PRINT
Aml Pages Home
Re[2]: Alt+Tab + своя миниатюра окна
От: Carc Россия https://vk.com/gosha_mazov
Дата: 01.03.23 11:11
Оценка:
Здравствуйте, ononim, Вы писали:

C>>Куда копать?

O>нынче окна всегда рисуются в offscreen, а когда надо его нарисовать кудато — на десктопе или в миниатюру — композитный менеджер копирует контент из offscreen картинки окна
O>https://ru.wikipedia.org/wiki/%D0%9A%D0%BE%D0%BC%D0%BF%D0%BE%D0%B7%D0%B8%D1%82%D0%BD%D1%8B%D0%B9_%D0%BC%D0%B5%D0%BD%D0%B5%D0%B4%D0%B6%D0%B5%D1%80_%D0%BE%D0%BA%D0%BE%D0%BD
Это всё здорово...
Но откуда сама картинка появляется в offscreen картинки окна? Я ж вижу, что остальные окна на миниатюрах похожи на "правду"? Например, та же старая студия VC++ 6.0, а она то что уж точно ни сном, ни духом про DWM_*
Aml Pages Home
Re[3]: Alt+Tab + своя миниатюра окна
От: ononim  
Дата: 01.03.23 11:24
Оценка:
O>>нынче окна всегда рисуются в offscreen, а когда надо его нарисовать кудато — на десктопе или в миниатюру — композитный менеджер копирует контент из offscreen картинки окна
O>>https://ru.wikipedia.org/wiki/%D0%9A%D0%BE%D0%BC%D0%BF%D0%BE%D0%B7%D0%B8%D1%82%D0%BD%D1%8B%D0%B9_%D0%BC%D0%B5%D0%BD%D0%B5%D0%B4%D0%B6%D0%B5%D1%80_%D0%BE%D0%BA%D0%BE%D0%BD
C>Это всё здорово...
C>Но откуда сама картинка появляется в offscreen картинки окна? Я ж вижу, что остальные окна на миниатюрах похожи на "правду"? Например, та же старая студия VC++ 6.0, а она то что уж точно ни сном, ни духом про DWM_*
Ну тебе приходит WM_ERASEBKGND WM_PAINT ты рисуешь в них в HDC, так вот это HDC — и есть offcreen image.
То есть картинка в миниатюре и картинка собственно окна — это одна и та же картинка, их невозможно както раздельно рисовать, если только для этого не сделали специальную фичу.
Как много веселых ребят, и все делают велосипед...
Re[4]: Alt+Tab + своя миниатюра окна
От: Carc Россия https://vk.com/gosha_mazov
Дата: 01.03.23 11:39
Оценка:
Здравствуйте, ononim, Вы писали:

O>>>нынче окна всегда рисуются в offscreen, а когда надо его нарисовать кудато — на десктопе или в миниатюру — композитный менеджер копирует контент из offscreen картинки окна

O>>>https://ru.wikipedia.org/wiki/%D0%9A%D0%BE%D0%BC%D0%BF%D0%BE%D0%B7%D0%B8%D1%82%D0%BD%D1%8B%D0%B9_%D0%BC%D0%B5%D0%BD%D0%B5%D0%B4%D0%B6%D0%B5%D1%80_%D0%BE%D0%BA%D0%BE%D0%BD
C>>Это всё здорово...
C>>Но откуда сама картинка появляется в offscreen картинки окна? Я ж вижу, что остальные окна на миниатюрах похожи на "правду"? Например, та же старая студия VC++ 6.0, а она то что уж точно ни сном, ни духом про DWM_*
O>Ну тебе приходит WM_ERASEBKGND WM_PAINT ты рисуешь в них в HDC, так вот это HDC — и есть offcreen image.
O>То есть картинка в миниатюре и картинка собственно окна — это одна и та же картинка, их невозможно както раздельно рисовать, если только для этого не сделали специальную фичу.
Да в том то всё и дело.

Что WM_ERASEBKGND, WM_PAINT приходят, я в них всё и рисую (посредь окна иконка + текст).
Судя по логам, я там точно оказываюсь.
Но миниатюра в Винде просто банальное пустое окно с белым фоном. Хотя окно точно моё: и иконка, и текст мои — видно невооруженным взглядом.
Но явно не берется отрисованная картинка из моей прорисовки...
Aml Pages Home
Re[5]: Alt+Tab + своя миниатюра окна
От: ononim  
Дата: 01.03.23 11:43
Оценка:
C>Что WM_ERASEBKGND, WM_PAINT приходят, я в них всё и рисую (посредь окна иконка + текст).
C>Судя по логам, я там точно оказываюсь.
C>Но миниатюра в Винде просто банальное пустое окно с белым фоном. Хотя окно точно моё: и иконка, и текст мои — видно невооруженным взглядом.
C>Но явно не берется отрисованная картинка из моей прорисовки...
нууу, хз
1 код отрисовки в студию (хотя я давно уже под винду не писал, но мож кто другой увидит косяк)
2 может потерялось при масштабировании? Если шрифт 32й поставить — тоже не видно?
Как много веселых ребят, и все делают велосипед...
Re[6]: Alt+Tab + своя миниатюра окна
От: Carc Россия https://vk.com/gosha_mazov
Дата: 01.03.23 11:51
Оценка:
Здравствуйте, ononim, Вы писали:

C>>Что WM_ERASEBKGND, WM_PAINT приходят, я в них всё и рисую (посредь окна иконка + текст).

C>>Судя по логам, я там точно оказываюсь.
C>>Но миниатюра в Винде просто банальное пустое окно с белым фоном. Хотя окно точно моё: и иконка, и текст мои — видно невооруженным взглядом.
C>>Но явно не берется отрисованная картинка из моей прорисовки...
O>нууу, хз
O>2 может потерялось при масштабировании? Если шрифт 32й поставить — тоже не видно?
Дык и иконки не видно, не только отрисованного текста.

O>1 код отрисовки в студию (хотя я давно уже под винду не писал, но мож кто другой увидит косяк)


static
void DoDraw(const HWND hwnd, const HDC hdc, const HICON hIcon)
{
    CLogger::WriteLog(TEXT("DoDraw"));

    TCHAR szText[MAX_PATH+1]={0} ;
    const UINT nGT=GetWindowText(hwnd, szText, ARRAYSIZE(szText) - 1);
    ATLASSERT(nGT);

    CRect rC;
    GetClientRect(hwnd,&rC);

    

    const HBRUSH hBrBk=GetSysColorBrush(INDEX_BK_COLOR);
    ::FillRect(hdc,&rC, hBrBk);

    if (hIcon) {
        CSize sizeIcon(IconUtil::GetIconSize(hIcon));

        const int x=rC.Width()/2 - sizeIcon.cx/2;
        const int y=rC.Height()/2 - sizeIcon.cy/2;

        ::DrawIconEx(hdc,x,y, hIcon
            ,sizeIcon.cx,sizeIcon.cy,0,hBrBk
            ,DI_NORMAL );
    }

    if (nGT > 0) {
        const CAutoGDIBkMode bk_mode(hdc, TRANSPARENT);//автокласс ::SetBkMode, в деструкторе вернет старый BkMode
        const CAutoGDIColor_Text color_text(hdc, GetSysColor(INDEX_TEXT_COLOR));//тот же автокласс но для SetTextColor
        
        ::DrawText(hdc, szText,nGT,&rC
            , DT_LEFT|DT_TOP|DT_SINGLELINE);
    }

}

LRESULT On_WmEraseBkgn(const HWND hwnd, const WPARAM wParam,const HICON h)
{
    const HDC hdc= (HDC)wParam;
    DoDraw(hwnd, hdc,h);

    return 1;//0;
}


//Оконная
LRESULT CWndAltTabIcon::_ALTTabWindowProc(HWND hwnd
                                          , UINT uMsg
                                          , WPARAM wParam
                                          , LPARAM lParam)
{
    ///ATLTRACE(TEXT("_ALTTabWindowProc = %X\n"),uMsg);
    
    CWndAltTabIcon* const pClass=(WM_CREATE == uMsg ? NULL : GetPointerFromHWND(hwnd));
    if (WM_CREATE != uMsg) {
        //ASSERT(pClass);
    }

#ifndef WM_DWMSENDICONICLIVEPREVIEWBITMAP   
    enum {WM_DWMSENDICONICLIVEPREVIEWBITMAP=0x0326};
#endif//#ifndef WM_DWMSENDICONICLIVEPREVIEWBITMAP   
    
    switch(uMsg) {
    case WM_ERASEBKGND:
        return On_WmEraseBkgn(hwnd,wParam,pClass->m_hIconLarge);
        break;
}
Aml Pages Home
Re[7]: Alt+Tab + своя миниатюра окна
От: ononim  
Дата: 01.03.23 12:08
Оценка:
O>>2 может потерялось при масштабировании? Если шрифт 32й поставить — тоже не видно?
C>Дык и иконки не видно, не только отрисованного текста.
O>>1 код отрисовки в студию (хотя я давно уже под винду не писал, но мож кто другой увидит косяк)
C>[ccode]
А где обработка WM_PAINT? Хотя бы пустая — содержащая BeginPaint/EndPaint — хотя не уверен что даже такое отработает адекватно..
Как много веселых ребят, и все делают велосипед...
Re[8]: Alt+Tab + своя миниатюра окна
От: Carc Россия https://vk.com/gosha_mazov
Дата: 01.03.23 12:18
Оценка:
Здравствуйте, ononim, Вы писали:

O>>>2 может потерялось при масштабировании? Если шрифт 32й поставить — тоже не видно?

C>>Дык и иконки не видно, не только отрисованного текста.
O>>>1 код отрисовки в студию (хотя я давно уже под винду не писал, но мож кто другой увидит косяк)
C>>
O>А где обработка WM_PAINT? Хотя бы пустая - содержащая BeginPaint/EndPaint - хотя не уверен что даже такое отработает адекватно..
[ccode]
LRESULT On_WmPaint(const HWND hwnd,const HICON h)
{
    PAINTSTRUCT ps;
    const HDC hdc=::BeginPaint(hwnd,&ps);
        //GetDC(hwnd);
    ASSERT(hdc) ;
    if (NULL == hdc)
        return 0;

    DoDraw(hwnd, hdc,h);
    EndPaint(hwnd, &ps);
    //ReleaseDC(hwnd, hdc);

    return 0;    
}

//в оконной 
....
    case WM_PAINT:
        DefWindowProc(hwnd , uMsg, wParam, lParam);
        return On_WmPaint(hwnd, pClass->m_hIconLarge);
        break;
Aml Pages Home
Re[9]: Alt+Tab + своя миниатюра окна
От: ononim  
Дата: 01.03.23 12:23
Оценка: 1 (1)
C> case WM_PAINT:
C> DefWindowProc(hwnd , uMsg, wParam, lParam);
C> return On_WmPaint(hwnd, pClass->m_hIconLarge);
C> break;
DefWindowProc тут лишняя
Как много веселых ребят, и все делают велосипед...
Re[10]: Alt+Tab + своя миниатюра окна
От: Carc Россия https://vk.com/gosha_mazov
Дата: 01.03.23 12:27
Оценка:
Здравствуйте, ononim, Вы писали:

C>> case WM_PAINT:

C>> DefWindowProc(hwnd , uMsg, wParam, lParam);
C>> return On_WmPaint(hwnd, pClass->m_hIconLarge);
C>> break;
O>DefWindowProc тут лишняя
Да, пока копипастил в форум и сам заметил. Убрал вызов DefWindowProc — всё то же самое... В миниатюре пустая клиентская область моего окна.
Aml Pages Home
Re[11]: Alt+Tab + своя миниатюра окна
От: ononim  
Дата: 01.03.23 12:43
Оценка:
C>Да, пока копипастил в форум и сам заметил. Убрал вызов DefWindowProc — всё то же самое... В миниатюре пустая клиентская область моего окна.
Ну теперь вроде бы норм, но меня еще смущает название CWndAltTabIcon — оно как бы намекает что у вас там какое то спецокно для альттаба, соответсвенно возникают сомнения в том что винда решает в альтабе рисовать именно это окно, а не какое то другое. Что у него за стили, адекватный ли у него размер и вообще состояние?
Как много веселых ребят, и все делают велосипед...
Re[12]: Alt+Tab + своя миниатюра окна
От: Carc Россия https://vk.com/gosha_mazov
Дата: 01.03.23 15:37
Оценка:
Здравствуйте, ononim, Вы писали:

C>>Да, пока копипастил в форум и сам заметил. Убрал вызов DefWindowProc — всё то же самое... В миниатюре пустая клиентская область моего окна.

O>Ну теперь вроде бы норм, но меня еще смущает название CWndAltTabIcon — оно как бы намекает что у вас там какое то спецокно для альттаба, соответсвенно возникают сомнения в том что винда решает в альтабе рисовать именно это окно, а не какое то другое. Что у него за стили, адекватный ли у него размер и вообще состояние?
Окно невидимое (без WS_VISIBLE), размеры 100 на 100 примерно, я это фактически вижу в миниатюре...
    const CString strClassName=бла_бла_боа();
    
    WNDCLASS wc={0};
    wc.style=CS_HREDRAW|CS_VREDRAW;
    wc.lpfnWndProc=_ALTTabWindowProc;
    wc.lpszClassName=(LPCTSTR)strClassName;
    //wc.hIcon=CAppObjects::LoadSmallIcon(_Module.m_hInst,IDR_MAINFRAME);
    wc.hIcon=hIconLarge;
    wc.hInstance=hModule;
    wc.hCursor=LoadCursor(NULL,MAKEINTRESOURCE(IDC_ARROW));
    wc.hbrBackground=(HBRUSH)GetStockObject(WHITE_BRUSH);
    //wc.hbrBackground=GetSysColorBrush(INDEX_BK_COLOR);
    const ATOM atom=RegisterClass(&wc);
    
    const DWORD dwStyle=
         WS_CAPTION
        |WS_CLIPSIBLINGS
        |WS_OVERLAPPED
        |WS_SYSMENU
        ;

    const DWORD dwExStyle=WS_EX_LEFT
        |WS_EX_LTRREADING
        |WS_EX_RIGHTSCROLLBAR
        |WS_EX_WINDOWEDGE
        |WS_EX_CONTROLPARENT
        ;

    
    const HWND hwnd=::CreateWindowEx(dwExStyle
        ,wc.lpszClassName
        ,lpszText
        ,dwStyle,POS_XY,POS_XY,POS_HEIGHT,POS_HEIGHT //тут как раз размеры X , Y - отрицательные (за краем экрана) width/height - 100
        ,hwndParent
        ,NULL
        ,NULL
        ,(LPVOID)this
        );
        
    //...
    const BOOL bCreated=::IsWindow(hwnd);
Aml Pages Home
Re[13]: Alt+Tab + своя миниатюра окна
От: ononim  
Дата: 01.03.23 15:43
Оценка:
C>Окно невидимое (без WS_VISIBLE), размеры 100 на 100 примерно, я это фактически вижу в миниатюре...
хаха, вот и слон... а если его сделать видимым?
Как много веселых ребят, и все делают велосипед...
Re[14]: Alt+Tab + своя миниатюра окна
От: Carc Россия https://vk.com/gosha_mazov
Дата: 01.03.23 16:19
Оценка:
Здравствуйте, ononim, Вы писали:

C>>Окно невидимое (без WS_VISIBLE), размеры 100 на 100 примерно, я это фактически вижу в миниатюре...

O>хаха, вот и слон... а если его сделать видимым?
Ничерта — все то же самое. Создаю с WS_VISIBLE, убрал перехват обработки WM_SHOWWINDOW — всё равно. Пустая клиентская область...
Aml Pages Home
Отредактировано 01.03.2023 16:21 Carc . Предыдущая версия .
Re[15]: Alt+Tab + своя миниатюра окна
От: ononim  
Дата: 01.03.23 18:09
Оценка:
C>>>Окно невидимое (без WS_VISIBLE), размеры 100 на 100 примерно, я это фактически вижу в миниатюре...
O>>хаха, вот и слон... а если его сделать видимым?
C>Ничерта — все то же самое. Создаю с WS_VISIBLE, убрал перехват обработки WM_SHOWWINDOW — всё равно. Пустая клиентская область...
WS_EX_APPWINDOW (extended style) наличствует?
Как много веселых ребят, и все делают велосипед...
Re[16]: Alt+Tab + своя миниатюра окна
От: Carc Россия https://vk.com/gosha_mazov
Дата: 01.03.23 18:37
Оценка:
Здравствуйте, ononim, Вы писали:

C>>>>Окно невидимое (без WS_VISIBLE), размеры 100 на 100 примерно, я это фактически вижу в миниатюре...

O>>>хаха, вот и слон... а если его сделать видимым?
C>>Ничерта — все то же самое. Создаю с WS_VISIBLE, убрал перехват обработки WM_SHOWWINDOW — всё равно. Пустая клиентская область...
O>WS_EX_APPWINDOW (extended style) наличствует?
Нет.
Но
а) Попробовал в _DEBUG использовать. Ничего не меняется.
б) Вообще говоря, я не могу использовать WS_EX_APPWINDOW — вся затея этого CWndAltTabIcon для одного: чтобы окно (иконка, текст) были в списке Alt+Tab, а некое основное окно было скрыто (например упали в трей, а окно приложения скрыли). Тогда можно подняться из трея не только мышом, но и с клавы перебираясь до айтема в списке по Alt+Tab. По сути то, этот самый CWndAltTabIcon окно-заглушка, которая ретранслирует некоторые сообщения из своей оконной процедуры в то самое "некое основное окно".... В принципе функционал рабочий, и применятся во вполне рабочих проектах. Но только с миниюатурами какая-то непонятка.
Aml Pages Home
Re: Alt+Tab + своя миниатюра окна
От: kov_serg Россия  
Дата: 01.03.23 20:38
Оценка: 18 (2)
Здравствуйте, Carc, Вы писали:

C>Куда копать?

https://learn.microsoft.com/en-us/windows/win32/shell/taskbar-extensions
https://devblogs.microsoft.com/oldnewthing/20130225-00/?p=5153
https://learn.microsoft.com/ru-ru/previous-versions/windows/desktop/legacy/ee663597(v=vs.85)
https://github.com/microsoft/Windows-classic-samples/tree/main/Samples/Win7Samples/winui/shell/appshellintegration/TaskbarThumbnailToolbar

Оно позволяет указать какую часть окна показывать:

Например 1 на 1 пиксель, а остальное изобразить на кнопке
Отредактировано 01.03.2023 21:45 kov_serg . Предыдущая версия . Еще …
Отредактировано 01.03.2023 20:49 kov_serg . Предыдущая версия .
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.