2 * PROJECT: ReactOS Picture and Fax Viewer
3 * FILE: dll/win32/shimgvw/shimgvw.c
5 * PROGRAMMERS: Dmitry Chapyshev (dmitry@reactos.org)
6 * Katayama Hirofumi MZ (katayama.hirofumi.mz@gmail.com)
9 #define WIN32_NO_STATUS
11 #define COM_NO_WINDOWS_H
36 SHIMGVW_SETTINGS shiSettings
;
37 SHIMGVW_FILENODE
*currentFile
;
39 WNDPROC PrevProc
= NULL
;
41 HWND hDispWnd
, hToolBar
;
46 UINT ZoomPercents
= 100;
47 static const UINT ZoomSteps
[] =
49 10, 25, 50, 100, 200, 400, 800, 1600
52 static void ZoomInOrOut(BOOL bZoomIn
)
56 if (bZoomIn
) /* zoom in */
59 for (i
= 0; i
< ARRAYSIZE(ZoomSteps
); ++i
)
61 if (ZoomPercents
< ZoomSteps
[i
])
64 if (i
== ARRAYSIZE(ZoomSteps
))
65 ZoomPercents
= MAX_ZOOM
;
67 ZoomPercents
= ZoomSteps
[i
];
69 /* update tool bar buttons */
70 SendMessage(hToolBar
, TB_ENABLEBUTTON
, IDC_ZOOMM
, TRUE
);
71 if (ZoomPercents
>= MAX_ZOOM
)
72 SendMessage(hToolBar
, TB_ENABLEBUTTON
, IDC_ZOOMP
, FALSE
);
74 SendMessage(hToolBar
, TB_ENABLEBUTTON
, IDC_ZOOMP
, TRUE
);
78 /* find previous step */
79 for (i
= ARRAYSIZE(ZoomSteps
); i
> 0; )
82 if (ZoomSteps
[i
] < ZoomPercents
)
86 ZoomPercents
= MIN_ZOOM
;
88 ZoomPercents
= ZoomSteps
[i
];
90 /* update tool bar buttons */
91 SendMessage(hToolBar
, TB_ENABLEBUTTON
, IDC_ZOOMP
, TRUE
);
92 if (ZoomPercents
<= MIN_ZOOM
)
93 SendMessage(hToolBar
, TB_ENABLEBUTTON
, IDC_ZOOMM
, FALSE
);
95 SendMessage(hToolBar
, TB_ENABLEBUTTON
, IDC_ZOOMM
, TRUE
);
99 InvalidateRect(hDispWnd
, NULL
, TRUE
);
102 static void ResetZoom(void)
105 UINT ImageWidth
, ImageHeight
;
107 /* get disp window size and image size */
108 GetClientRect(hDispWnd
, &Rect
);
109 GdipGetImageWidth(image
, &ImageWidth
);
110 GdipGetImageHeight(image
, &ImageHeight
);
112 /* compare two aspect rates. same as
113 (ImageHeight / ImageWidth < Rect.bottom / Rect.right) in real */
114 if (ImageHeight
* Rect
.right
< Rect
.bottom
* ImageWidth
)
116 if (Rect
.right
< ImageWidth
)
118 /* it's large, shrink it */
119 ZoomPercents
= (Rect
.right
* 100) / ImageWidth
;
123 /* it's small. show as original size */
129 if (Rect
.bottom
< ImageHeight
)
131 /* it's large, shrink it */
132 ZoomPercents
= (Rect
.bottom
* 100) / ImageHeight
;
136 /* it's small. show as original size */
142 /* ToolBar Buttons */
143 static const TBBUTTON Buttons
[] =
144 { /* iBitmap, idCommand, fsState, fsStyle, bReserved[2], dwData, iString */
145 {TBICON_PREV
, IDC_PREV
, TBSTATE_ENABLED
, BTNS_BUTTON
, {0}, 0, 0},
146 {TBICON_NEXT
, IDC_NEXT
, TBSTATE_ENABLED
, BTNS_BUTTON
, {0}, 0, 0},
147 {15, 0, TBSTATE_ENABLED
, BTNS_SEP
, {0}, 0, 0},
148 {TBICON_ZOOMP
, IDC_ZOOMP
, TBSTATE_ENABLED
, BTNS_BUTTON
, {0}, 0, 0},
149 {TBICON_ZOOMM
, IDC_ZOOMM
, TBSTATE_ENABLED
, BTNS_BUTTON
, {0}, 0, 0},
150 {15, 0, TBSTATE_ENABLED
, BTNS_SEP
, {0}, 0, 0},
151 {TBICON_ROT1
, IDC_ROT1
, TBSTATE_ENABLED
, BTNS_BUTTON
, {0}, 0, 0},
152 {TBICON_ROT2
, IDC_ROT2
, TBSTATE_ENABLED
, BTNS_BUTTON
, {0}, 0, 0},
153 {15, 0, TBSTATE_ENABLED
, BTNS_SEP
, {0}, 0, 0},
154 {TBICON_SAVE
, IDC_SAVE
, TBSTATE_ENABLED
, BTNS_BUTTON
, {0}, 0, 0},
155 {TBICON_PRINT
, IDC_PRINT
, TBSTATE_ENABLED
, BTNS_BUTTON
, {0}, 0, 0},
158 static void pLoadImage(LPWSTR szOpenFileName
)
160 /* check file presence */
161 if (GetFileAttributesW(szOpenFileName
) == 0xFFFFFFFF)
163 DPRINT1("File %s not found!\n", szOpenFileName
);
168 GdipLoadImageFromFile(szOpenFileName
, &image
);
171 DPRINT1("GdipLoadImageFromFile() failed\n");
179 InvalidateRect(hDispWnd
, NULL
, TRUE
);
182 static void pSaveImageAs(HWND hwnd
)
185 ImageCodecInfo
*codecInfo
;
186 WCHAR szSaveFileName
[MAX_PATH
];
195 GdipGetImageEncodersSize(&num
, &size
);
196 codecInfo
= malloc(size
);
199 DPRINT1("malloc() failed in pSaveImageAs()\n");
203 GdipGetImageEncoders(num
, size
, codecInfo
);
204 GdipGetImageRawFormat(image
, &rawFormat
);
208 for (j
= 0; j
< num
; ++j
)
210 // Every pair needs space for the Description, twice the Extensions, 1 char for the space, 2 for the braces and 2 for the NULL terminators.
211 sizeRemain
= sizeRemain
+ (((wcslen(codecInfo
[j
].FormatDescription
) + (wcslen(codecInfo
[j
].FilenameExtension
) * 2) + 5) * sizeof(WCHAR
)));
214 /* Add two more chars for the last terminator */
215 sizeRemain
= sizeRemain
+ (sizeof(WCHAR
) * 2);
217 szFilterMask
= malloc(sizeRemain
);
220 DPRINT1("cannot allocate memory for filter mask in pSaveImageAs()");
225 ZeroMemory(szSaveFileName
, sizeof(szSaveFileName
));
226 ZeroMemory(szFilterMask
, sizeRemain
);
227 ZeroMemory(&sfn
, sizeof(sfn
));
228 sfn
.lStructSize
= sizeof(sfn
);
229 sfn
.hwndOwner
= hwnd
;
230 sfn
.hInstance
= hInstance
;
231 sfn
.lpstrFile
= szSaveFileName
;
232 sfn
.lpstrFilter
= szFilterMask
;
233 sfn
.nMaxFile
= MAX_PATH
;
234 sfn
.Flags
= OFN_OVERWRITEPROMPT
| OFN_HIDEREADONLY
;
238 for (j
= 0; j
< num
; ++j
)
240 StringCbPrintfExW(c
, sizeRemain
, &c
, &sizeRemain
, 0, L
"%ls (%ls)", codecInfo
[j
].FormatDescription
, codecInfo
[j
].FilenameExtension
);
242 /* Skip the NULL character */
244 sizeRemain
-= sizeof(*c
);
246 StringCbPrintfExW(c
, sizeRemain
, &c
, &sizeRemain
, 0, L
"%ls", codecInfo
[j
].FilenameExtension
);
248 /* Skip the NULL character */
250 sizeRemain
-= sizeof(*c
);
252 if (IsEqualGUID(&rawFormat
, &codecInfo
[j
].FormatID
) != FALSE
)
254 sfn
.nFilterIndex
= j
+ 1;
258 if (GetSaveFileNameW(&sfn
))
260 if (GdipSaveImageToFile(image
, szSaveFileName
, &codecInfo
[sfn
.nFilterIndex
- 1].Clsid
, NULL
) != Ok
)
262 DPRINT1("GdipSaveImageToFile() failed\n");
271 pLoadImageFromNode(SHIMGVW_FILENODE
*node
, HWND hwnd
)
273 WCHAR szTitleBuf
[800];
279 c
= wcsrchr(node
->FileName
, '\\');
285 LoadStringW(hInstance
, IDS_APPTITLE
, szResStr
, ARRAYSIZE(szResStr
));
286 StringCbPrintfW(szTitleBuf
, sizeof(szTitleBuf
), L
"%ls%ls%ls", szResStr
, L
" - ", c
);
287 SetWindowTextW(hwnd
, szTitleBuf
);
291 GdipDisposeImage(image
);
294 pLoadImage(node
->FileName
);
298 static SHIMGVW_FILENODE
*
299 pBuildFileList(LPWSTR szFirstFile
)
303 WCHAR szSearchPath
[MAX_PATH
];
304 WCHAR szSearchMask
[MAX_PATH
];
305 WCHAR szFileTypes
[MAX_PATH
];
306 WIN32_FIND_DATAW findData
;
307 SHIMGVW_FILENODE
*currentNode
= NULL
;
308 SHIMGVW_FILENODE
*root
= NULL
;
309 SHIMGVW_FILENODE
*conductor
= NULL
;
310 ImageCodecInfo
*codecInfo
;
315 StringCbCopyW(szSearchPath
, sizeof(szSearchPath
), szFirstFile
);
316 PathRemoveFileSpecW(szSearchPath
);
318 GdipGetImageDecodersSize(&num
, &size
);
319 codecInfo
= malloc(size
);
322 DPRINT1("malloc() failed in pLoadFileList()\n");
326 GdipGetImageDecoders(num
, size
, codecInfo
);
328 root
= malloc(sizeof(SHIMGVW_FILENODE
));
331 DPRINT1("malloc() failed in pLoadFileList()\n");
338 for (j
= 0; j
< num
; ++j
)
340 StringCbCopyW(szFileTypes
, sizeof(szFileTypes
), codecInfo
[j
].FilenameExtension
);
342 extension
= wcstok(szFileTypes
, L
";");
343 while (extension
!= NULL
)
345 PathCombineW(szSearchMask
, szSearchPath
, extension
);
347 hFindHandle
= FindFirstFileW(szSearchMask
, &findData
);
348 if (hFindHandle
!= INVALID_HANDLE_VALUE
)
352 PathCombineW(conductor
->FileName
, szSearchPath
, findData
.cFileName
);
354 // compare the name of the requested file with the one currently found.
355 // if the name matches, the current node is returned by the function.
356 if (wcscmp(szFirstFile
, conductor
->FileName
) == 0)
358 currentNode
= conductor
;
361 conductor
->Next
= malloc(sizeof(SHIMGVW_FILENODE
));
363 // if malloc fails, make circular what we have and return it
364 if (!conductor
->Next
)
366 DPRINT1("malloc() failed in pLoadFileList()\n");
368 conductor
->Next
= root
;
369 root
->Prev
= conductor
;
371 FindClose(hFindHandle
);
376 conductor
->Next
->Prev
= conductor
;
377 conductor
= conductor
->Next
;
379 while (FindNextFileW(hFindHandle
, &findData
) != 0);
381 FindClose(hFindHandle
);
384 extension
= wcstok(NULL
, L
";");
388 // we now have a node too much in the list. In case the requested file was not found,
389 // we use this node to store the name of it, otherwise we free it.
390 if (currentNode
== NULL
)
392 StringCchCopyW(conductor
->FileName
, MAX_PATH
, szFirstFile
);
393 currentNode
= conductor
;
397 conductor
= conductor
->Prev
;
398 free(conductor
->Next
);
401 // link the last node with the first one to make the list circular
402 conductor
->Next
= root
;
403 root
->Prev
= conductor
;
404 conductor
= currentNode
;
412 pFreeFileList(SHIMGVW_FILENODE
*root
)
414 SHIMGVW_FILENODE
*conductor
;
416 root
->Prev
->Next
= NULL
;
422 root
= conductor
->Next
;
428 ImageView_UpdateWindow(HWND hwnd
)
430 InvalidateRect(hwnd
, NULL
, FALSE
);
435 ImageView_DrawImage(HWND hwnd
)
437 GpGraphics
*graphics
;
438 UINT ImageWidth
, ImageHeight
;
439 INT ZoomedWidth
, ZoomedHeight
, x
, y
;
444 hdc
= BeginPaint(hwnd
, &ps
);
447 DPRINT1("BeginPaint() failed\n");
451 GdipCreateFromHDC(hdc
, &graphics
);
454 DPRINT1("GdipCreateFromHDC() failed\n");
458 GdipGetImageWidth(image
, &ImageWidth
);
459 GdipGetImageHeight(image
, &ImageHeight
);
461 if (GetClientRect(hwnd
, &rect
))
463 FillRect(hdc
, &rect
, (HBRUSH
)GetStockObject(WHITE_BRUSH
));
465 ZoomedWidth
= (ImageWidth
* ZoomPercents
) / 100;
466 ZoomedHeight
= (ImageHeight
* ZoomPercents
) / 100;
468 x
= (rect
.right
- ZoomedWidth
) / 2;
469 y
= (rect
.bottom
- ZoomedHeight
) / 2;
471 DPRINT("x = %d, y = %d, ImageWidth = %u, ImageHeight = %u\n");
472 DPRINT("rect.right = %ld, rect.bottom = %ld\n", rect
.right
, rect
.bottom
);
473 DPRINT("ZoomPercents = %d, ZoomedWidth = %d, ZoomedHeight = %d\n",
474 ZoomPercents
, ZoomedWidth
, ZoomedWidth
);
476 if (ZoomPercents
% 100 == 0)
478 GdipSetInterpolationMode(graphics
, InterpolationModeNearestNeighbor
);
479 GdipSetSmoothingMode(graphics
, SmoothingModeNone
);
483 GdipSetInterpolationMode(graphics
, InterpolationModeHighQualityBilinear
);
484 GdipSetSmoothingMode(graphics
, SmoothingModeHighQuality
);
487 Rectangle(hdc
, x
- 1, y
- 1, x
+ ZoomedWidth
+ 1, y
+ ZoomedHeight
+ 1);
488 GdipDrawImageRectI(graphics
, image
, x
, y
, ZoomedWidth
, ZoomedHeight
);
490 GdipDeleteGraphics(graphics
);
495 ImageView_LoadSettings()
500 if (RegOpenKeyEx(HKEY_CURRENT_USER
, _T("Software\\ReactOS\\shimgvw"), 0, KEY_READ
, &hKey
) == ERROR_SUCCESS
)
502 dwSize
= sizeof(SHIMGVW_SETTINGS
);
503 if (RegQueryValueEx(hKey
, _T("Settings"), NULL
, NULL
, (LPBYTE
)&shiSettings
, &dwSize
) == ERROR_SUCCESS
)
516 ImageView_SaveSettings(HWND hwnd
)
521 ShowWindow(hwnd
, SW_HIDE
);
522 wp
.length
= sizeof(WINDOWPLACEMENT
);
523 GetWindowPlacement(hwnd
, &wp
);
525 shiSettings
.Left
= wp
.rcNormalPosition
.left
;
526 shiSettings
.Top
= wp
.rcNormalPosition
.top
;
527 shiSettings
.Right
= wp
.rcNormalPosition
.right
;
528 shiSettings
.Bottom
= wp
.rcNormalPosition
.bottom
;
529 shiSettings
.Maximized
= (IsZoomed(hwnd
) || (wp
.flags
& WPF_RESTORETOMAXIMIZED
));
531 if (RegCreateKeyEx(HKEY_CURRENT_USER
, _T("Software\\ReactOS\\shimgvw"), 0, NULL
,
532 REG_OPTION_NON_VOLATILE
, KEY_WRITE
, NULL
, &hKey
, NULL
) == ERROR_SUCCESS
)
534 RegSetValueEx(hKey
, _T("Settings"), 0, REG_BINARY
, (LPBYTE
)&shiSettings
, sizeof(SHIMGVW_SETTINGS
));
540 ImageView_CreateToolBar(HWND hwnd
)
542 INT numButtons
= sizeof(Buttons
) / sizeof(Buttons
[0]);
544 hToolBar
= CreateWindowEx(0, TOOLBARCLASSNAME
, NULL
,
545 WS_CHILD
| WS_VISIBLE
| TBSTYLE_FLAT
| CCS_BOTTOM
| TBSTYLE_TOOLTIPS
,
550 HIMAGELIST hImageList
;
552 SendMessage(hToolBar
, TB_SETEXTENDEDSTYLE
,
553 0, TBSTYLE_EX_HIDECLIPPEDBUTTONS
);
555 SendMessage(hToolBar
, TB_BUTTONSTRUCTSIZE
,
556 sizeof(Buttons
[0]), 0);
558 hImageList
= ImageList_Create(TB_IMAGE_WIDTH
, TB_IMAGE_HEIGHT
, ILC_MASK
| ILC_COLOR24
, 1, 1);
560 ImageList_AddMasked(hImageList
, LoadImage(hInstance
, MAKEINTRESOURCE(IDB_PREVICON
), IMAGE_BITMAP
,
561 TB_IMAGE_WIDTH
, TB_IMAGE_HEIGHT
, LR_DEFAULTCOLOR
), RGB(255, 255, 255));
563 ImageList_AddMasked(hImageList
, LoadImage(hInstance
, MAKEINTRESOURCE(IDB_NEXTICON
), IMAGE_BITMAP
,
564 TB_IMAGE_WIDTH
, TB_IMAGE_HEIGHT
, LR_DEFAULTCOLOR
), RGB(255, 255, 255));
566 ImageList_AddMasked(hImageList
, LoadImage(hInstance
, MAKEINTRESOURCE(IDB_ZOOMPICON
), IMAGE_BITMAP
,
567 TB_IMAGE_WIDTH
, TB_IMAGE_HEIGHT
, LR_DEFAULTCOLOR
), RGB(255, 255, 255));
569 ImageList_AddMasked(hImageList
, LoadImage(hInstance
, MAKEINTRESOURCE(IDB_ZOOMMICON
), IMAGE_BITMAP
,
570 TB_IMAGE_WIDTH
, TB_IMAGE_HEIGHT
, LR_DEFAULTCOLOR
), RGB(255, 255, 255));
572 ImageList_AddMasked(hImageList
, LoadImage(hInstance
, MAKEINTRESOURCE(IDB_SAVEICON
), IMAGE_BITMAP
,
573 TB_IMAGE_WIDTH
, TB_IMAGE_HEIGHT
, LR_DEFAULTCOLOR
), RGB(255, 255, 255));
575 ImageList_AddMasked(hImageList
, LoadImage(hInstance
, MAKEINTRESOURCE(IDB_PRINTICON
), IMAGE_BITMAP
,
576 TB_IMAGE_WIDTH
, TB_IMAGE_HEIGHT
, LR_DEFAULTCOLOR
), RGB(255, 255, 255));
578 ImageList_AddMasked(hImageList
, LoadImage(hInstance
, MAKEINTRESOURCE(IDB_ROT1ICON
), IMAGE_BITMAP
,
579 TB_IMAGE_WIDTH
, TB_IMAGE_HEIGHT
, LR_DEFAULTCOLOR
), RGB(255, 255, 255));
581 ImageList_AddMasked(hImageList
, LoadImage(hInstance
, MAKEINTRESOURCE(IDB_ROT2ICON
), IMAGE_BITMAP
,
582 TB_IMAGE_WIDTH
, TB_IMAGE_HEIGHT
, LR_DEFAULTCOLOR
), RGB(255, 255, 255));
584 if (hImageList
== NULL
) return FALSE
;
586 ImageList_Destroy((HIMAGELIST
)SendMessage(hToolBar
, TB_SETIMAGELIST
,
587 0, (LPARAM
)hImageList
));
589 SendMessage(hToolBar
, TB_ADDBUTTONS
,
590 numButtons
, (LPARAM
)Buttons
);
599 ImageView_DispWndProc(HWND hwnd
, UINT Message
, WPARAM wParam
, LPARAM lParam
)
605 ImageView_DrawImage(hwnd
);
609 return CallWindowProc(PrevProc
, hwnd
, Message
, wParam
, lParam
);
613 ImageView_InitControls(HWND hwnd
)
615 MoveWindow(hwnd
, shiSettings
.Left
, shiSettings
.Top
,
616 shiSettings
.Right
- shiSettings
.Left
,
617 shiSettings
.Bottom
- shiSettings
.Top
, TRUE
);
619 if (shiSettings
.Maximized
) ShowWindow(hwnd
, SW_MAXIMIZE
);
621 hDispWnd
= CreateWindowEx(0, WC_STATIC
, _T(""),
622 WS_CHILD
| WS_VISIBLE
,
623 0, 0, 0, 0, hwnd
, NULL
, hInstance
, NULL
);
625 SetClassLongPtr(hDispWnd
, GCL_STYLE
, CS_HREDRAW
| CS_VREDRAW
);
626 PrevProc
= (WNDPROC
) SetWindowLongPtr(hDispWnd
, GWL_WNDPROC
, (LPARAM
) ImageView_DispWndProc
);
628 ImageView_CreateToolBar(hwnd
);
632 ImageView_OnMouseWheel(HWND hwnd
, INT x
, INT y
, INT zDelta
, UINT fwKeys
)
636 ZoomInOrOut(zDelta
> 0);
641 ImageView_WndProc(HWND hwnd
, UINT Message
, WPARAM wParam
, LPARAM lParam
)
647 ImageView_InitControls(hwnd
);
652 switch (LOWORD(wParam
))
655 PostMessage(hwnd
, WM_COMMAND
, MAKEWPARAM(IDC_PREV
, BN_CLICKED
), (LPARAM
)NULL
);
659 PostMessage(hwnd
, WM_COMMAND
, MAKEWPARAM(IDC_NEXT
, BN_CLICKED
), (LPARAM
)NULL
);
670 currentFile
= currentFile
->Prev
;
671 pLoadImageFromNode(currentFile
, hwnd
);
677 currentFile
= currentFile
->Next
;
678 pLoadImageFromNode(currentFile
, hwnd
);
701 GdipImageRotateFlip(image
, Rotate270FlipNone
);
702 ImageView_UpdateWindow(hwnd
);
708 GdipImageRotateFlip(image
, Rotate90FlipNone
);
709 ImageView_UpdateWindow(hwnd
);
718 ImageView_OnMouseWheel(hwnd
,
719 GET_X_LPARAM(lParam
), GET_Y_LPARAM(lParam
),
720 (SHORT
)HIWORD(wParam
), (UINT
)LOWORD(wParam
));
725 LPNMHDR pnmhdr
= (LPNMHDR
)lParam
;
727 switch (pnmhdr
->code
)
729 case TTN_GETDISPINFO
:
734 lpttt
= (LPTOOLTIPTEXT
)lParam
;
735 idButton
= (UINT
)lpttt
->hdr
.idFrom
;
736 lpttt
->hinst
= hInstance
;
741 lpttt
->lpszText
= MAKEINTRESOURCE(IDS_TOOLTIP_PREV_PIC
);
744 lpttt
->lpszText
= MAKEINTRESOURCE(IDS_TOOLTIP_NEXT_PIC
);
747 lpttt
->lpszText
= MAKEINTRESOURCE(IDS_TOOLTIP_ZOOM_IN
);
750 lpttt
->lpszText
= MAKEINTRESOURCE(IDS_TOOLTIP_ZOOM_OUT
);
753 lpttt
->lpszText
= MAKEINTRESOURCE(IDS_TOOLTIP_SAVEAS
);
756 lpttt
->lpszText
= MAKEINTRESOURCE(IDS_TOOLTIP_PRINT
);
759 lpttt
->lpszText
= MAKEINTRESOURCE(IDS_TOOLTIP_ROT_COUNCW
);
762 lpttt
->lpszText
= MAKEINTRESOURCE(IDS_TOOLTIP_ROT_CLOCKW
);
772 LPRECT pRect
= (LPRECT
)lParam
;
773 if (pRect
->right
-pRect
->left
< 350)
774 pRect
->right
= pRect
->left
+ 350;
776 if (pRect
->bottom
-pRect
->top
< 290)
777 pRect
->bottom
= pRect
->top
+ 290;
783 SendMessage(hToolBar
, TB_AUTOSIZE
, 0, 0);
784 GetWindowRect(hToolBar
, &rc
);
785 MoveWindow(hDispWnd
, 1, 1, LOWORD(lParam
) - 1, HIWORD(lParam
) - (rc
.bottom
- rc
.top
) - 1, TRUE
);
786 /* is it maximized or restored? */
787 if (wParam
== SIZE_MAXIMIZED
|| wParam
== SIZE_RESTORED
)
796 ImageView_SaveSettings(hwnd
);
797 SetWindowLongPtr(hDispWnd
, GWL_WNDPROC
, (LPARAM
) PrevProc
);
803 return DefWindowProc(hwnd
, Message
, wParam
, lParam
);
807 ImageView_CreateWindow(HWND hwnd
, LPWSTR szFileName
)
809 struct GdiplusStartupInput gdiplusStartupInput
;
810 ULONG_PTR gdiplusToken
;
811 WNDCLASS WndClass
= {0};
813 WCHAR szInitialFile
[MAX_PATH
];
817 if (!ImageView_LoadSettings())
819 shiSettings
.Maximized
= FALSE
;
820 shiSettings
.Left
= 0;
822 shiSettings
.Right
= 520;
823 shiSettings
.Bottom
= 400;
827 gdiplusStartupInput
.GdiplusVersion
= 1;
828 gdiplusStartupInput
.DebugEventCallback
= NULL
;
829 gdiplusStartupInput
.SuppressBackgroundThread
= FALSE
;
830 gdiplusStartupInput
.SuppressExternalCodecs
= FALSE
;
832 GdiplusStartup(&gdiplusToken
, &gdiplusStartupInput
, NULL
);
833 pLoadImage(szFileName
);
836 WndClass
.lpszClassName
= _T("shimgvw_window");
837 WndClass
.lpfnWndProc
= ImageView_WndProc
;
838 WndClass
.hInstance
= hInstance
;
839 WndClass
.style
= CS_HREDRAW
| CS_VREDRAW
;
840 WndClass
.hIcon
= LoadIcon(hInstance
, MAKEINTRESOURCE(IDI_APPICON
));
841 WndClass
.hCursor
= LoadCursor(hInstance
, IDC_ARROW
);
842 WndClass
.hbrBackground
= NULL
; /* less flicker */
844 if (!RegisterClass(&WndClass
)) return -1;
846 LoadString(hInstance
, IDS_APPTITLE
, szBuf
, sizeof(szBuf
) / sizeof(TCHAR
));
847 hMainWnd
= CreateWindow(_T("shimgvw_window"), szBuf
,
848 WS_OVERLAPPEDWINDOW
| WS_VISIBLE
| WS_CAPTION
,
849 CW_USEDEFAULT
, CW_USEDEFAULT
,
850 0, 0, NULL
, NULL
, hInstance
, NULL
);
852 // make sure the path has no quotes on it
853 wcscpy(szInitialFile
, szFileName
);
854 PathUnquoteSpacesW(szInitialFile
);
856 currentFile
= pBuildFileList(szInitialFile
);
859 pLoadImageFromNode(currentFile
, hMainWnd
);
863 ShowWindow(hMainWnd
, SW_SHOW
);
864 UpdateWindow(hMainWnd
);
867 while(GetMessage(&msg
,NULL
,0,0))
869 TranslateMessage(&msg
);
870 DispatchMessageW(&msg
);
873 pFreeFileList(currentFile
);
876 GdipDisposeImage(image
);
877 GdiplusShutdown(gdiplusToken
);
882 ImageView_FullscreenW(HWND hwnd
, HINSTANCE hInst
, LPCWSTR path
, int nShow
)
884 ImageView_CreateWindow(hwnd
, (LPWSTR
)path
);
888 ImageView_Fullscreen(HWND hwnd
, HINSTANCE hInst
, LPCWSTR path
, int nShow
)
890 ImageView_CreateWindow(hwnd
, (LPWSTR
)path
);
894 ImageView_FullscreenA(HWND hwnd
, HINSTANCE hInst
, LPCSTR path
, int nShow
)
896 WCHAR szFile
[MAX_PATH
];
898 if (MultiByteToWideChar(CP_ACP
, 0, (char*)path
, strlen((char*)path
)+1, szFile
, MAX_PATH
))
900 ImageView_CreateWindow(hwnd
, (LPWSTR
)szFile
);
905 ImageView_PrintTo(HWND hwnd
, HINSTANCE hInst
, LPCWSTR path
, int nShow
)
907 DPRINT("ImageView_PrintTo() not implemented\n");
911 ImageView_PrintToA(HWND hwnd
, HINSTANCE hInst
, LPCSTR path
, int nShow
)
913 DPRINT("ImageView_PrintToA() not implemented\n");
917 ImageView_PrintToW(HWND hwnd
, HINSTANCE hInst
, LPCWSTR path
, int nShow
)
919 DPRINT("ImageView_PrintToW() not implemented\n");
923 DllMain(IN HINSTANCE hinstDLL
,
925 IN LPVOID lpvReserved
)
929 case DLL_PROCESS_ATTACH
:
930 case DLL_THREAD_ATTACH
:
931 hInstance
= hinstDLL
;