xoblite™ / Blackbox for Windows bb5 | RC6 preview | 0.25.2.14
http://xoblite.net/
PreviewItem Class Reference

#include <PreviewItem.h>

Public Member Functions

 PreviewItem (HINSTANCE hInstance)
 
 ~PreviewItem ()
 
void UpdatePreviewItemWindow (int x, int y, char *path)
 
void Show (int x, int y, char *path)
 
void Hide ()
 
int GetWidth ()
 

Public Attributes

HINSTANCE hPreviewItemInstance
 
HWND hBlackboxWnd
 
HWND hPreviewItemWnd
 
HDC cachedBackground
 
int newItemX
 
int newItemY
 
char newItemPath [MAX_PATH]
 
int PreviewItemX
 
int PreviewItemY
 
int PreviewItemWidth
 
int PreviewItemHeight
 
bool PreviewItemHidden
 

Friends

LRESULT CALLBACK PreviewItemWindowProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
 

Constructor & Destructor Documentation

◆ PreviewItem()

PreviewItem::PreviewItem ( HINSTANCE hInstance)
43{
44 hPreviewItemWnd = NULL;
46 hPreviewItemInstance = hInstance;
47 cachedBackground = CreateCompatibleDC(NULL);
50 PreviewItemHidden = true;
51
52 // Start GDI+...
53// GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);
54
55 //====================
56
57 // Register window class...
58 WNDCLASS wc;
59 ZeroMemory(&wc, sizeof(wc));
60 wc.hInstance = hPreviewItemInstance; // hInstance
61 wc.lpfnWndProc = PreviewItemWindowProc; // Window procedure
62 wc.lpszClassName = szPreviewItemName; // Window class name
63 wc.hbrBackground = NULL; // No class background brush
64 wc.style = NULL; // Class styles
65 wc.hCursor = LoadCursor(NULL, IDC_ARROW); // Always display the regular arrow cursor
66
67 if (!RegisterClass(&wc))
68 {
69 MessageBox(0, "Error registering preview item window class!", szPreviewItemName, MB_OK | MB_ICONERROR | MB_TOPMOST);
70 Log("PreviewItem: Error registering window class!", NULL);
71 return;
72 }
73
74 // Create preview item window...
75 hPreviewItemWnd = CreateWindowEx(
76 WS_EX_TOOLWINDOW | WS_EX_NOACTIVATE | WS_EX_LAYERED, // window style
77 szPreviewItemName, // window class
78 NULL, // window name
79 WS_POPUP | WS_CLIPCHILDREN | WS_CLIPSIBLINGS, // window parameters
80 PreviewItemX, // x position
81 PreviewItemY, // y position
82 PreviewItemWidth, // window width
83 PreviewItemHeight, // window height
84 NULL, //pDesktop->hDesktopWnd, // owner window
85 NULL, // no menu
86 hPreviewItemInstance, // hInstance
87 NULL // no window creation data
88 );
89
90 if (!hPreviewItemWnd)
91 {
92 UnregisterClass(szPreviewItemName, hPreviewItemInstance); // Unregister window class
93 MessageBox(0, "Error creating preview item window!", szPreviewItemName, MB_OK | MB_ICONERROR | MB_TOPMOST);
94 Log("PreviewItem: Error creating window!", NULL);
95 return;
96 }
97
98 ShowWindow(hPreviewItemWnd, SW_HIDE);
99 SetWindowPos(hPreviewItemWnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOACTIVATE | SWP_NOSIZE | SWP_NOMOVE);
100 MakeSticky(hPreviewItemWnd); // Make the preview item window sticky... (i.e. shown regardless of the current workspace)
101
102 //====================
103
104 // Subscribe to Blackbox messages applicable to menu preview items...
106}
void MakeSticky(HWND window)
Definition BBApi.cpp:2965
#define WS_EX_LAYERED
Definition BBApi.cpp:61
void Log(LPCSTR des, LPCSTR line)
Definition BBApi.cpp:638
Settings * pSettings
Definition Blackbox.cpp:46
HWND GetBBWnd()
Definition BBApi.cpp:128
#define BB_REGISTERMESSAGE
Definition BBApi.h:142
int previewItemMessageSubscription[]
Definition PreviewItem.cpp:38
const char szPreviewItemName[]
Definition PreviewItem.cpp:33
int newItemX
Definition PreviewItem.h:64
int PreviewItemY
Definition PreviewItem.h:66
friend LRESULT CALLBACK PreviewItemWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
Definition PreviewItem.cpp:125
bool PreviewItemHidden
Definition PreviewItem.h:67
HINSTANCE hPreviewItemInstance
Definition PreviewItem.h:59
int newItemY
Definition PreviewItem.h:64
HWND hBlackboxWnd
Definition PreviewItem.h:60
int PreviewItemWidth
Definition PreviewItem.h:66
int PreviewItemHeight
Definition PreviewItem.h:66
HDC cachedBackground
Definition PreviewItem.h:62
HWND hPreviewItemWnd
Definition PreviewItem.h:61
int PreviewItemX
Definition PreviewItem.h:66
int scalingFactorHiDPI
Definition Settings.h:327

◆ ~PreviewItem()

PreviewItem::~PreviewItem ( )
111{
112 // Unsubscribe to previously subscribed Blackbox messages...
114
115 if (hPreviewItemWnd) DestroyWindow(hPreviewItemWnd); // Destroy window....
116 UnregisterClass(szPreviewItemName, hPreviewItemInstance); // Unregister window class...
117 if (cachedBackground) DeleteDC(cachedBackground); // Delete the cached gradient...
118
119 // Shutdown GDI+...
120// GdiplusShutdown(gdiplusToken);
121}
#define BB_UNREGISTERMESSAGE
Definition BBApi.h:143

Member Function Documentation

◆ UpdatePreviewItemWindow()

void PreviewItem::UpdatePreviewItemWindow ( int x,
int y,
char * path )
179{
180 if (PreviewItemHidden) return;
181
182 // Load the image using GDI+ to add support for JPG, PNG etc...
183 // (nb. regular GDI LoadImage() only supports BMP images. GDI+ startup/shutdown is performed by MenuCommon.)
184 HDC buf = CreateCompatibleDC(cachedBackground);
185 HBITMAP image = NULL;
186 wchar_t imagePathWC[MAX_PATH];
187// mbstowcs(imagePathWC, path, MAX_PATH);
188 MultiByteToWideChar(CP_ACP, 0, path, strlen(path)+1, imagePathWC, MAX_PATH);
189 Bitmap* bitmap = new Bitmap(imagePathWC, FALSE);
190 int imageWidth = bitmap->GetWidth();
191 int imageHeight = bitmap->GetHeight();
192 bitmap->GetHBITMAP(0, &image);
193 delete bitmap;
194
195 //====================
196
197 PreviewItemX = x;
198
199 if (image == NULL) // Image loading failed...
200 {
203 }
204 else // Image loading succeeded...
205 {
206 PreviewItemHeight = (PreviewItemWidth * imageHeight) / imageWidth;
208 }
209
210 int screenY = GetSystemMetrics(SM_YVIRTUALSCREEN);
211 if (PreviewItemY < screenY) PreviewItemY = screenY;
212 int screenHeight = GetSystemMetrics(SM_CYVIRTUALSCREEN);
213 if ((PreviewItemY + PreviewItemHeight) > screenHeight) PreviewItemY = screenHeight - PreviewItemHeight;
214
215 //====================
216
217 RECT r;
218 SetRect(&r, 0, 0, PreviewItemWidth, PreviewItemHeight);
219
220 HDC hdc = GetWindowDC(hPreviewItemWnd);
221 HBITMAP bufbmp = CreateCompatibleBitmap(hdc, r.right - r.left, r.bottom - r.top);
222 DeleteObject(SelectObject(cachedBackground, bufbmp));
223 ReleaseDC(hPreviewItemWnd, hdc);
224
225 //====================
226
227 // Draw background...
228 SetRect(&r, 0, 0, PreviewItemWidth, PreviewItemHeight);
229 HBRUSH brush = CreateSolidBrush(0x000000);
230 FillRect(cachedBackground, &r, brush);
231 DeleteObject(brush);
232
233 //====================
234
235 int previewBorder = 2 * pSettings->scalingFactorHiDPI;
236
237 if (image != NULL)
238 {
239 // Draw scaled down image...
240 DeleteObject(SelectObject(buf, image));
241 SetStretchBltMode(cachedBackground, HALFTONE);
242 StretchBlt(cachedBackground, previewBorder, previewBorder, PreviewItemWidth-(previewBorder*2), PreviewItemHeight-(previewBorder*2), buf, 0, 0, imageWidth, imageHeight, SRCCOPY);
243 // ### Below: While AlphaBlend() can be used to draw 32bpp ARGB images with per pixel alpha transparency, it also scales images down
244 // much less smoothly than StretchBlt() as it reverts from HALFTONE (i.e. pixel averaging) to COLORONCOLOR (i.e. pixel deleting) mode;
245 // for more information see https://docs.microsoft.com/en-us/windows/win32/api/wingdi/nf-wingdi-alphablend ###
246// BLENDFUNCTION bf;
247// ZeroMemory(&bf, sizeof(BLENDFUNCTION));
248// bf.BlendOp = AC_SRC_OVER;
249// bf.SourceConstantAlpha = 255;
250// bf.AlphaFormat = AC_SRC_ALPHA;
251// AlphaBlend(cachedBackground, previewBorder, previewBorder, PreviewItemWidth-(previewBorder*2), PreviewItemHeight-(previewBorder*2), buf, 0, 0, imageWidth, imageHeight, bf);
252 DeleteObject(image);
253 }
254 else
255 {
256 // Draw the path string only if the image couldn't be loaded...
257 HFONT font = CreateFont(10, 0, 0, 0, FW_NORMAL, false, false, false, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH | FF_DONTCARE, "Segoe UI");
258 HGDIOBJ oldfont = SelectObject(cachedBackground, font);
259 SetBkMode(cachedBackground, TRANSPARENT);
260 InflateRect(&r, -previewBorder, -previewBorder);
261 DrawTextWithEffects(cachedBackground, r, path, DT_LEFT | DT_VCENTER | DT_NOPREFIX | DT_PATH_ELLIPSIS, 0xffffff, false, 0, false, 0, 0, 0);
262 DeleteObject(SelectObject(cachedBackground, oldfont));
263 }
264
265 DeleteDC(buf);
266
267 //====================
268
269 if (bufbmp) DeleteObject(bufbmp);
270
271 POINT pt;
272 pt.x = PreviewItemX, pt.y = PreviewItemY;
273 POINT ptSrc;
274 ptSrc.x = 0, ptSrc.y = 0;
275
276 BLENDFUNCTION bf;
277 bf.BlendOp = AC_SRC_OVER;
278 bf.BlendFlags = 0;
279 bf.AlphaFormat = AC_SRC_ALPHA;
280 bf.SourceConstantAlpha = (unsigned char)255;
281
282 SIZE windowSize = { PreviewItemWidth, PreviewItemHeight };
283 BOOL result = UpdateLayeredWindow(hPreviewItemWnd, NULL, &pt, &windowSize, cachedBackground, &ptSrc, 0, &bf, ULW_OPAQUE);
284/*
285 if (!cachedBackground) SendMessage(GetBBWnd(), BB_CONSOLEMESSAGE, (WPARAM)CONSOLE_INFORMATION_MESSAGE, (LPARAM)"xoblite -> PreviewItem -> Invalid cachedBackground!");
286
287 if (result == 0)
288 {
289 int error = GetLastError();
290 char msg[255];
291 sprintf(msg, "xoblite -> PreviewItem -> UpdateLayeredWindow failed! [error code %d]", error);
292 SendMessage(GetBBWnd(), BB_CONSOLEMESSAGE, (WPARAM)CONSOLE_ERROR_MESSAGE, (LPARAM)msg);
293 }
294*/
295}
void DrawTextWithEffects(HDC hdc, RECT r, LPSTR text, unsigned int format, COLORREF textColor, bool outline, COLORREF outlineColor, bool shadow, COLORREF shadowColor, int shadowX, int shadowY)
Definition BBApi.cpp:3519

◆ Show()

void PreviewItem::Show ( int x,
int y,
char * path )
300{
301 if (!strlen(path)) return;
302
304
305 // Save the new preview item parameters...
306 newItemX = x;
307 newItemY = y;
308 strcpy(newItemPath, path);
309
310 // ... and display it after a short delay...
311 // (nb. we do this to get smoother fast scrolling through parent menus,
312 // i.e. no loading of images on every single entry while scrolling)
313 SetTimer(pPreviewItem->hPreviewItemWnd, PREVIEW_ITEM_TIMER, 200, (TIMERPROC)NULL);
314}
PreviewItem * pPreviewItem
Definition Blackbox.cpp:45
#define PREVIEW_ITEM_TIMER
Definition PreviewItem.h:41
char newItemPath[MAX_PATH]
Definition PreviewItem.h:65

◆ Hide()

void PreviewItem::Hide ( )
317{
319 {
321 PreviewItemHidden = true;
322 ShowWindow(hPreviewItemWnd, SW_HIDE);
323 }
324}

◆ GetWidth()

int PreviewItem::GetWidth ( )
327{
328 return PreviewItemWidth;
329}

Friends And Related Symbol Documentation

◆ PreviewItemWindowProc

LRESULT CALLBACK PreviewItemWindowProc ( HWND hwnd,
UINT message,
WPARAM wParam,
LPARAM lParam )
friend
126{
127
128 switch (message)
129 {
130 case WM_TIMER:
131 {
132 if (wParam == PREVIEW_ITEM_TIMER)
133 {
137 ShowWindow(pPreviewItem->hPreviewItemWnd, SW_SHOWNOACTIVATE);
138 SetWindowPos(pPreviewItem->hPreviewItemWnd, HWND_TOP, 0, 0, 0, 0, SWP_NOACTIVATE | SWP_NOSIZE | SWP_NOMOVE | SWP_NOOWNERZORDER);
139 }
140
141 return 0;
142 }
143 break;
144
145 //====================
146
147 case BB_RECONFIGURE:
148 {
150 }
151 break;
152
153 //====================
154
155 case WM_CLOSE:
156 return 0;
157
158 //====================
159
160 case WM_NCHITTEST:
161 return HTCLIENT;
162
163 //====================
164
165 default:
166 return DefWindowProc(hwnd, message, wParam, lParam);
167
168 //====================
169 }
170 return 0;
171}
#define BB_RECONFIGURE
Definition BBApi.h:147
void Hide()
Definition PreviewItem.cpp:316
void UpdatePreviewItemWindow(int x, int y, char *path)
Definition PreviewItem.cpp:178

Member Data Documentation

◆ hPreviewItemInstance

HINSTANCE PreviewItem::hPreviewItemInstance

◆ hBlackboxWnd

HWND PreviewItem::hBlackboxWnd

◆ hPreviewItemWnd

HWND PreviewItem::hPreviewItemWnd

◆ cachedBackground

HDC PreviewItem::cachedBackground

◆ newItemX

int PreviewItem::newItemX

◆ newItemY

int PreviewItem::newItemY

◆ newItemPath

char PreviewItem::newItemPath[MAX_PATH]

◆ PreviewItemX

int PreviewItem::PreviewItemX

◆ PreviewItemY

int PreviewItem::PreviewItemY

◆ PreviewItemWidth

int PreviewItem::PreviewItemWidth

◆ PreviewItemHeight

int PreviewItem::PreviewItemHeight

◆ PreviewItemHidden

bool PreviewItem::PreviewItemHidden