3 * PROJECT: ReactOS Picture and Fax Viewer
4 * FILE: dll/win32/shimgvw/shimgvw.c
6 * PROGRAMMER: Dmitry Chapyshev (dmitry@reactos.org)
26 SHIMGVW_SETTINGS shiSettings
;
27 WCHAR szOpenFileName
[MAX_PATH
];
29 HWND hDispWnd
, hToolBar
;
32 static const TBBUTTON Buttons
[] =
33 { /* iBitmap, idCommand, fsState, fsStyle, bReserved[2], dwData, iString */
34 {TBICON_PREV
, IDC_PREV
, TBSTATE_ENABLED
, BTNS_BUTTON
, {0}, 0, 0},
35 {TBICON_NEXT
, IDC_NEXT
, TBSTATE_ENABLED
, BTNS_BUTTON
, {0}, 0, 0},
36 {15, 0, TBSTATE_ENABLED
, BTNS_SEP
, {0}, 0, 0},
37 {TBICON_ZOOMP
, IDC_ZOOMP
, TBSTATE_ENABLED
, BTNS_BUTTON
, {0}, 0, 0},
38 {TBICON_ZOOMM
, IDC_ZOOMM
, TBSTATE_ENABLED
, BTNS_BUTTON
, {0}, 0, 0},
39 {15, 0, TBSTATE_ENABLED
, BTNS_SEP
, {0}, 0, 0},
40 {TBICON_ROT1
, IDC_ROT1
, TBSTATE_ENABLED
, BTNS_BUTTON
, {0}, 0, 0},
41 {TBICON_ROT2
, IDC_ROT2
, TBSTATE_ENABLED
, BTNS_BUTTON
, {0}, 0, 0},
42 {15, 0, TBSTATE_ENABLED
, BTNS_SEP
, {0}, 0, 0},
43 {TBICON_SAVE
, IDC_SAVE
, TBSTATE_ENABLED
, BTNS_BUTTON
, {0}, 0, 0},
44 {TBICON_PRINT
, IDC_PRINT
, TBSTATE_ENABLED
, BTNS_BUTTON
, {0}, 0, 0},
48 ImageView_DrawImage(HWND hwnd
)
52 UINT uImgWidth
, uImgHeight
;
53 UINT height
= 0, width
= 0, x
= 0, y
= 0;
58 if (GetFileAttributesW(szOpenFileName
) == 0xFFFFFFFF)
60 DPRINT1("File %s not found!\n", szOpenFileName
);
64 hdc
= BeginPaint(hwnd
, &ps
);
67 DPRINT1("BeginPaint() failed\n");
71 GdipCreateFromHDC(hdc
, &graphics
);
74 DPRINT1("GdipCreateFromHDC() failed\n");
79 GdipLoadImageFromFile(szOpenFileName
, &image
);
82 DPRINT1("GdipLoadImageFromFile() failed\n");
87 GdipGetImageWidth(image
, &uImgWidth
);
88 GdipGetImageHeight(image
, &uImgHeight
);
90 if (GetClientRect(hwnd
, &rect
))
92 FillRect(hdc
, &rect
, (HBRUSH
)COLOR_WINDOW
);
94 if ((rect
.right
== uImgWidth
)&&(rect
.bottom
== uImgHeight
))
96 x
= 0, y
= 0, width
= rect
.right
, height
= rect
.bottom
;
98 else if ((rect
.right
>= uImgWidth
)&&(rect
.bottom
>= uImgHeight
))
100 x
= (rect
.right
/2)-(uImgWidth
/2);
101 y
= (rect
.bottom
/2)-(uImgHeight
/2);
105 else if ((rect
.right
< uImgWidth
)||(rect
.bottom
< uImgHeight
))
107 if (rect
.bottom
< uImgHeight
)
109 height
= rect
.bottom
;
110 width
= uImgWidth
*(UINT
)rect
.bottom
/uImgHeight
;
111 x
= (rect
.right
/2)-(width
/2);
112 y
= (rect
.bottom
/2)-(height
/2);
114 if (rect
.right
< uImgWidth
)
117 height
= uImgHeight
*(UINT
)rect
.right
/uImgWidth
;
118 x
= (rect
.right
/2)-(width
/2);
119 y
= (rect
.bottom
/2)-(height
/2);
121 if ((height
> rect
.bottom
)||(width
> rect
.right
))
125 if (((int)width
- 1 < 0)||((int)height
- 1 < 0)) break;
128 y
= (rect
.bottom
/2)-(height
/2);
129 x
= (rect
.right
/2)-(width
/2);
130 if ((height
< rect
.bottom
)&&(width
< rect
.right
)) break;
134 else if ((rect
.right
<= uImgWidth
)&&(rect
.bottom
<= uImgHeight
))
136 height
= uImgHeight
*(UINT
)rect
.right
/uImgWidth
;
137 y
= (rect
.bottom
/2)-(height
/2);
140 if ((height
> rect
.bottom
)||(width
> rect
.right
))
144 if (((int)width
- 1 < 0)||((int)height
- 1 < 0)) break;
147 y
= (rect
.bottom
/2)-(height
/2);
148 x
= (rect
.right
/2)-(width
/2);
149 if ((height
< rect
.bottom
)&&(width
< rect
.right
)) break;
154 DPRINT1("x = %d\ny = %d\nWidth = %d\nHeight = %d\n\nrect.right = %d\nrect.bottom = %d\n\nuImgWidth = %d\nuImgHeight = %d", x
, y
, width
, height
, rect
.right
, rect
.bottom
, uImgWidth
, uImgHeight
);
155 GdipDrawImageRect(graphics
, image
, x
, y
, width
, height
);
163 ImageView_LoadSettings()
168 if (RegOpenKeyEx(HKEY_CURRENT_USER
, _T("Software\\ReactOS\\shimgvw"), 0, KEY_READ
, &hKey
) == ERROR_SUCCESS
)
170 dwSize
= sizeof(SHIMGVW_SETTINGS
);
171 if (RegQueryValueEx(hKey
, _T("Settings"), NULL
, NULL
, (LPBYTE
)&shiSettings
, &dwSize
) == ERROR_SUCCESS
)
184 ImageView_SaveSettings(HWND hwnd
)
189 ShowWindow(hwnd
, SW_HIDE
);
190 wp
.length
= sizeof(WINDOWPLACEMENT
);
191 GetWindowPlacement(hwnd
, &wp
);
193 shiSettings
.Left
= wp
.rcNormalPosition
.left
;
194 shiSettings
.Top
= wp
.rcNormalPosition
.top
;
195 shiSettings
.Right
= wp
.rcNormalPosition
.right
;
196 shiSettings
.Bottom
= wp
.rcNormalPosition
.bottom
;
197 shiSettings
.Maximized
= (IsZoomed(hwnd
) || (wp
.flags
& WPF_RESTORETOMAXIMIZED
));
199 if (RegCreateKeyEx(HKEY_CURRENT_USER
, _T("Software\\ReactOS\\shimgvw"), 0, NULL
,
200 REG_OPTION_NON_VOLATILE
, KEY_WRITE
, NULL
, &hKey
, NULL
) == ERROR_SUCCESS
)
202 RegSetValueEx(hKey
, _T("Settings"), 0, REG_BINARY
, (LPBYTE
)&shiSettings
, sizeof(SHIMGVW_SETTINGS
));
208 ImageView_CreateToolBar(HWND hwnd
)
210 INT numButtons
= sizeof(Buttons
) / sizeof(Buttons
[0]);
212 hToolBar
= CreateWindowEx(0, TOOLBARCLASSNAME
, NULL
,
213 WS_CHILD
| WS_VISIBLE
| TBSTYLE_FLAT
| CCS_BOTTOM
| TBSTYLE_TOOLTIPS
,
218 HIMAGELIST hImageList
;
220 SendMessage(hToolBar
, TB_SETEXTENDEDSTYLE
,
221 0, TBSTYLE_EX_HIDECLIPPEDBUTTONS
);
223 SendMessage(hToolBar
, TB_BUTTONSTRUCTSIZE
,
224 sizeof(Buttons
[0]), 0);
226 hImageList
= ImageList_Create(TB_IMAGE_WIDTH
, TB_IMAGE_HEIGHT
, ILC_MASK
| ILC_COLOR24
, 1, 1);
228 ImageList_AddMasked(hImageList
, LoadImage(hInstance
, MAKEINTRESOURCE(IDB_PREVICON
), IMAGE_BITMAP
,
229 TB_IMAGE_WIDTH
, TB_IMAGE_HEIGHT
, LR_DEFAULTCOLOR
), RGB(255, 255, 255));
231 ImageList_AddMasked(hImageList
, LoadImage(hInstance
, MAKEINTRESOURCE(IDB_NEXTICON
), IMAGE_BITMAP
,
232 TB_IMAGE_WIDTH
, TB_IMAGE_HEIGHT
, LR_DEFAULTCOLOR
), RGB(255, 255, 255));
234 ImageList_AddMasked(hImageList
, LoadImage(hInstance
, MAKEINTRESOURCE(IDB_ZOOMPICON
), IMAGE_BITMAP
,
235 TB_IMAGE_WIDTH
, TB_IMAGE_HEIGHT
, LR_DEFAULTCOLOR
), RGB(255, 255, 255));
237 ImageList_AddMasked(hImageList
, LoadImage(hInstance
, MAKEINTRESOURCE(IDB_ZOOMMICON
), IMAGE_BITMAP
,
238 TB_IMAGE_WIDTH
, TB_IMAGE_HEIGHT
, LR_DEFAULTCOLOR
), RGB(255, 255, 255));
240 ImageList_AddMasked(hImageList
, LoadImage(hInstance
, MAKEINTRESOURCE(IDB_SAVEICON
), IMAGE_BITMAP
,
241 TB_IMAGE_WIDTH
, TB_IMAGE_HEIGHT
, LR_DEFAULTCOLOR
), RGB(255, 255, 255));
243 ImageList_AddMasked(hImageList
, LoadImage(hInstance
, MAKEINTRESOURCE(IDB_PRINTICON
), IMAGE_BITMAP
,
244 TB_IMAGE_WIDTH
, TB_IMAGE_HEIGHT
, LR_DEFAULTCOLOR
), RGB(255, 255, 255));
246 ImageList_AddMasked(hImageList
, LoadImage(hInstance
, MAKEINTRESOURCE(IDB_ROT1ICON
), IMAGE_BITMAP
,
247 TB_IMAGE_WIDTH
, TB_IMAGE_HEIGHT
, LR_DEFAULTCOLOR
), RGB(255, 255, 255));
249 ImageList_AddMasked(hImageList
, LoadImage(hInstance
, MAKEINTRESOURCE(IDB_ROT2ICON
), IMAGE_BITMAP
,
250 TB_IMAGE_WIDTH
, TB_IMAGE_HEIGHT
, LR_DEFAULTCOLOR
), RGB(255, 255, 255));
252 if (hImageList
== NULL
) return FALSE
;
254 ImageList_Destroy((HIMAGELIST
)SendMessage(hToolBar
, TB_SETIMAGELIST
,
255 0, (LPARAM
)hImageList
));
257 SendMessage(hToolBar
, TB_ADDBUTTONS
,
258 numButtons
, (LPARAM
)Buttons
);
267 ImageView_InitControls(HWND hwnd
)
269 MoveWindow(hwnd
, shiSettings
.Left
, shiSettings
.Top
,
270 shiSettings
.Right
- shiSettings
.Left
,
271 shiSettings
.Bottom
- shiSettings
.Top
, TRUE
);
273 if (shiSettings
.Maximized
) ShowWindow(hwnd
, SW_MAXIMIZE
);
275 hDispWnd
= CreateWindowEx(WS_EX_TRANSPARENT
, _T("STATIC"), _T(""),
276 WS_CHILD
| WS_VISIBLE
,
277 0, 0, 0, 0, hwnd
, NULL
, hInstance
, NULL
);
279 ImageView_CreateToolBar(hwnd
);
283 ImageView_WndProc(HWND hwnd
, UINT Message
, WPARAM wParam
, LPARAM lParam
)
289 ImageView_InitControls(hwnd
);
327 LPNMHDR pnmhdr
= (LPNMHDR
)lParam
;
329 switch (pnmhdr
->code
)
331 case TTN_GETDISPINFO
:
336 lpttt
= (LPTOOLTIPTEXT
)lParam
;
337 idButton
= (UINT
)lpttt
->hdr
.idFrom
;
342 lpttt
->lpszText
= MAKEINTRESOURCE(IDS_TOOLTIP_PREV_PIC
);
345 lpttt
->lpszText
= MAKEINTRESOURCE(IDS_TOOLTIP_NEXT_PIC
);
348 lpttt
->lpszText
= MAKEINTRESOURCE(IDS_TOOLTIP_ZOOM_IN
);
351 lpttt
->lpszText
= MAKEINTRESOURCE(IDS_TOOLTIP_ZOOM_OUT
);
354 lpttt
->lpszText
= MAKEINTRESOURCE(IDS_TOOLTIP_SAVEAS
);
357 lpttt
->lpszText
= MAKEINTRESOURCE(IDS_TOOLTIP_PRINT
);
360 lpttt
->lpszText
= MAKEINTRESOURCE(IDS_TOOLTIP_ROT_COUNCW
);
363 lpttt
->lpszText
= MAKEINTRESOURCE(IDS_TOOLTIP_ROT_CLOCKW
);
373 ImageView_DrawImage(hDispWnd
);
379 LPRECT pRect
= (LPRECT
)lParam
;
380 if (pRect
->right
-pRect
->left
< 350)
381 pRect
->right
= pRect
->left
+ 350;
383 if (pRect
->bottom
-pRect
->top
< 290)
384 pRect
->bottom
= pRect
->top
+ 290;
390 MoveWindow(hDispWnd
, 1, 1, LOWORD(lParam
)-1, HIWORD(lParam
)-35, TRUE
);
391 SendMessage(hToolBar
, TB_AUTOSIZE
, 0, 0);
397 ImageView_SaveSettings(hwnd
);
403 return DefWindowProc(hwnd
, Message
, wParam
, lParam
);
407 ImageView_CreateWindow(HWND hwnd
, LPWSTR szFileName
)
409 struct GdiplusStartupInput gdiplusStartupInput
;
410 ULONG_PTR gdiplusToken
;
411 WNDCLASS WndClass
= {0};
416 wcscpy(szOpenFileName
, szFileName
);
418 if (!ImageView_LoadSettings())
420 shiSettings
.Maximized
= FALSE
;
421 shiSettings
.Left
= 0;
423 shiSettings
.Right
= 520;
424 shiSettings
.Bottom
= 400;
428 gdiplusStartupInput
.GdiplusVersion
= 1;
429 gdiplusStartupInput
.DebugEventCallback
= NULL
;
430 gdiplusStartupInput
.SuppressBackgroundThread
= 0;
431 gdiplusStartupInput
.SuppressExternalCodecs
= 0;
433 GdiplusStartup(&gdiplusToken
, &gdiplusStartupInput
, NULL
);
436 WndClass
.lpszClassName
= _T("shimgvw_window");
437 WndClass
.lpfnWndProc
= (WNDPROC
)ImageView_WndProc
;
438 WndClass
.hInstance
= hInstance
;
439 WndClass
.style
= CS_HREDRAW
| CS_VREDRAW
;
440 WndClass
.hIcon
= LoadIcon(hInstance
, MAKEINTRESOURCE(IDI_APPICON
));
441 WndClass
.hCursor
= LoadCursor(hInstance
, IDC_ARROW
);
442 WndClass
.hbrBackground
= (HBRUSH
)COLOR_WINDOW
;
444 if (!RegisterClass(&WndClass
)) return -1;
446 LoadString(hInstance
, IDS_APPTITLE
, szBuf
, sizeof(szBuf
) / sizeof(TCHAR
));
447 hMainWnd
= CreateWindow(_T("shimgvw_window"), szBuf
,
448 WS_OVERLAPPEDWINDOW
| WS_CLIPCHILDREN
| WS_VISIBLE
| WS_CAPTION
,
449 CW_USEDEFAULT
, CW_USEDEFAULT
,
450 0, 0, NULL
, NULL
, hInstance
, NULL
);
453 ShowWindow(hMainWnd
, SW_SHOW
);
454 UpdateWindow(hMainWnd
);
457 while(GetMessage(&msg
,NULL
,0,0))
459 TranslateMessage(&msg
);
460 DispatchMessageW(&msg
);
463 GdiplusShutdown(gdiplusToken
);
468 ImageView_FullscreenW(HWND hwnd
, HINSTANCE hInst
, LPCWSTR path
, int nShow
)
470 ImageView_CreateWindow(hwnd
, (LPWSTR
)path
);
474 ImageView_Fullscreen(HWND hwnd
, HINSTANCE hInst
, LPCWSTR path
, int nShow
)
476 ImageView_CreateWindow(hwnd
, (LPWSTR
)path
);
480 ImageView_FullscreenA(HWND hwnd
, HINSTANCE hInst
, LPCSTR path
, int nShow
)
482 WCHAR szFile
[MAX_PATH
];
484 if (MultiByteToWideChar(CP_ACP
, 0, (char*)path
, strlen((char*)path
)+1, szFile
, MAX_PATH
))
486 ImageView_CreateWindow(hwnd
, (LPWSTR
)szFile
);
491 ImageView_PrintTo(HWND hwnd
, HINSTANCE hInst
, LPCWSTR path
, int nShow
)
493 DPRINT("ImageView_PrintTo() not implemented\n");
497 ImageView_PrintToA(HWND hwnd
, HINSTANCE hInst
, LPCSTR path
, int nShow
)
499 DPRINT("ImageView_PrintToA() not implemented\n");
503 ImageView_PrintToW(HWND hwnd
, HINSTANCE hInst
, LPCWSTR path
, int nShow
)
505 DPRINT("ImageView_PrintToW() not implemented\n");
509 imageview_fullscreenW(HWND hwnd
, HINSTANCE hInst
, LPCWSTR path
, int nShow
)
511 DPRINT("ImageView_fullscreenW() not implemented\n");
515 DllMain(IN HINSTANCE hinstDLL
,
517 IN LPVOID lpvReserved
)
521 case DLL_PROCESS_ATTACH
:
522 case DLL_THREAD_ATTACH
:
523 hInstance
= hinstDLL
;