00001
00002
00003 #include <windows.h>
00004 #include <io.h>
00005 #include <stdio.h>
00006 #include <string.h>
00007 #include "viewer.h"
00008 #include "..\common\animate\about.h"
00009
00010 #if __SC__ || __WATCOMC__
00011 extern INT _argc;
00012 extern CHAR **_argv;
00013 #else
00014 extern INT __argc;
00015 extern CHAR **__argv;
00016 #endif
00017
00018 #if __SC__
00019 #pragma ZTC align 1
00020 #endif
00021
00022 #include "../common/mem.h"
00023
00024 #define FI_GIF 0
00025 #define FI_TGA 1
00026
00027 #define FI_DIB 3
00028 #define FI_TIF 4
00029 #define FI_JPG 5
00030 #define FI_PNG 6
00031 #define PALVERSION 0x300
00032 #define MAXPALETTE 256
00033 #define MAXTEXT 256
00034
00035 extern short read_gif_image(char *, short);
00036 extern unsigned char p_red[],p_green[],p_blue[];
00037 extern int colourmap_size,x_size,y_size,gif_iLace;
00038
00039 HWND hWndApp = NULL;
00040 HINSTANCE hInst = NULL;
00041 HPALETTE hpalCurrent = NULL;
00042 HBITMAP hbmCurrent = NULL;
00043 RGBQUAD *pRgb = NULL;
00044 LPSTR lpBitmapHeader = NULL;
00045 LPSTR lpBitmapBits = NULL;
00046
00047 #define BOUND(x,min,max) ((x) < (min) ? (min) : ((x) > (max) ? (max) : (x)))
00048 #define SWAP(x,y) ((x)^=(y)^=(x)^=(y))
00049 #define MIN(x,y) (((x) <= (y)) : x ? y)
00050 #define StartWait() hcurSave = SetCursor(LoadCursor(NULL,IDC_WAIT))
00051 #define EndWait() SetCursor(hcurSave)
00052
00053 #define ISDIB(bft) ((bft) == BFT_BITMAP)
00054
00055 #define ALIGNULONG(i) ((i+3)/4*4)
00056
00057 #define WIDTHBYTES(i) ((i+31)/32*4)
00058
00059 static char *szViewClass="OFX:ViewClass";
00060
00061 char IniFilename[256],
00062 IniSection[] = "VIEWER";
00063 static SYSTEM_INFO sys_info;
00064 static int DisplayWidth,DisplayHeight,DisplayBits,DisplayPlanes,
00065 xScreen,yScreen,rowcount,rowinc,x4_size,file_format=FI_GIF;
00066 static int from_renderer=0;
00067 static LPSTR pixels;
00068 static char CurrentDirFile[256],CurrentDirectory[256],CurrentFile[256];
00069 static POINT ptSize;
00070 static DWORD fdwStyle = WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU |
00071 WS_MAXIMIZEBOX | WS_MINIMIZEBOX | WS_THICKFRAME;
00072 static HCURSOR hcurSave;
00073
00074 static int identify_file_format(void);
00075 static int ErrMsg(char *sz,...);
00076 static void LoadErrMsg(int id);
00077 static void PutMsg(char *s);
00078 BOOL CALLBACK AboutDlgProc(HWND hwnd,UINT msg,WPARAM wparam,LPARAM lparam);
00079 LRESULT CALLBACK MainWndProc(HWND hWnd,UINT iMessage,WPARAM wParam,LPARAM lParam);
00080 BOOL MenuCommand(HWND hWnd, WORD id, LONG lparam);
00081 static void FreeDib(void);
00082 static void SizeWindow(HWND hWnd);
00083 static void SetScrollRanges(HWND hwnd);
00084 static HPALETTE CreateImagePalette(LPBITMAPINFOHEADER lpbi);
00085 static WORD NumColours(LPBITMAPINFOHEADER lpbi);
00086 static void GetRealClientRect(HWND hwnd, PRECT lprc);
00087 static void AppPaint(HWND hWnd, HDC hDC, int x, int y);
00088 static HBITMAP BitmapFromDib(LPSTR lpHeader,LPSTR lpBits,HPALETTE hpal);
00089 static int celview(HWND hWnd);
00090 static int dibview(HWND hWnd);
00091 static int tifview(HWND hWnd);
00092 static int jpgview(HWND hWnd);
00093
00094 static char WIN32_environment[512];
00095
00096 char *R_GetEnv(char const *aa){
00097 if(GetEnvironmentVariable((LPTSTR)aa,(LPTSTR)WIN32_environment,256) == 0)
00098 return NULL;
00099 return WIN32_environment;
00100 }
00101
00102 static PSTR FileInPath(PSTR pstrPath){
00103 PSTR pstr;
00104 pstr = pstrPath + strlen(pstrPath);
00105 while (pstr > pstrPath) {
00106 pstr = (AnsiPrev(pstrPath, pstr));
00107 if (*pstr == '\\' || *pstr == ':' || *pstr == '/') {
00108 pstr = (AnsiNext(pstr));
00109 break;
00110 }
00111 }
00112 return pstr;
00113 }
00114
00115 int Viewer(HINSTANCE hInstance){
00116 MSG msg;
00117 HWND hDesktopWnd,hWnd;
00118 HDC hDCcaps;
00119 WNDCLASS wndclass;
00120 hInst = hInstance;
00121 hDesktopWnd = GetDesktopWindow();
00122 hDCcaps = GetDC(hDesktopWnd);
00123 DisplayWidth= GetDeviceCaps(hDCcaps,HORZRES);
00124 DisplayHeight= GetDeviceCaps(hDCcaps,VERTRES);
00125 DisplayBits= GetDeviceCaps(hDCcaps,BITSPIXEL);
00126 DisplayPlanes= GetDeviceCaps(hDCcaps,PLANES);
00127 ReleaseDC(hDesktopWnd,hDCcaps);
00128 GetSystemInfo(&sys_info);
00129 wndclass.style = 0;
00130 wndclass.lpfnWndProc = (WNDPROC)MainWndProc;
00131 wndclass.cbClsExtra = 0 ;
00132 wndclass.cbWndExtra = 0 ;
00133 wndclass.hInstance = hInstance ;
00134 wndclass.hIcon = LoadIcon(hInst, "VIEWICON");
00135 wndclass.hCursor = LoadCursor (NULL, IDC_ARROW) ;
00136 wndclass.hbrBackground = GetStockObject (WHITE_BRUSH) ;
00137 wndclass.lpszMenuName = "ShowMenu" ;
00138 wndclass.lpszClassName = szViewClass;
00139 if (!RegisterClass (&wndclass)) return FALSE ;
00140 xScreen = GetSystemMetrics (SM_CXSCREEN) ;
00141 yScreen = GetSystemMetrics (SM_CYSCREEN) ;
00142 hWnd = CreateWindow(
00143 szViewClass,
00144 "Viewer",
00145 fdwStyle,
00146 CW_USEDEFAULT,
00147 CW_USEDEFAULT,
00148 xScreen / 2,
00149 yScreen / 2,
00150 NULL,
00151 NULL,
00152 hInstance,
00153 NULL) ;
00154 if(hWnd == NULL)return FALSE;
00155 ShowWindow (hWndApp = hWnd, SW_SHOWNA);
00156 while(GetMessage (&msg, NULL, 0, 0)) {
00157 TranslateMessage (&msg);
00158 DispatchMessage (&msg);
00159 }
00160 FreeDib();
00161 UnregisterClass(wndclass.lpszClassName,wndclass.hInstance);
00162 return msg.wParam;
00163 }
00164
00165 LRESULT CALLBACK MainWndProc(HWND hWnd,UINT iMessage,WPARAM wParam,
00166 LPARAM lParam){
00167 PAINTSTRUCT ps;
00168 HDC hDC;
00169 int i,iPos,iMax,iMin,dn;
00170 RECT rc;
00171 switch (iMessage) {
00172 case WM_CREATE:
00173 SetWindowPos(hWnd,HWND_TOPMOST,0,0,0,0,SWP_NOMOVE|SWP_NOSIZE);
00174 break;
00175
00176
00177
00178
00179
00180
00181
00182 case WM_SYSCOMMAND:
00183 switch(LOWORD(wParam & 0xfff0)){
00184 case SC_CLOSE:
00185 PostMessage(hWnd,WM_COMMAND,IDM_HIDE,0);
00186 break;
00187 default:
00188 return(DefWindowProc(hWnd,iMessage,wParam,lParam));
00189 break;
00190 }
00191 break;
00192 case WM_COMMAND:
00193 return MenuCommand(hWnd,LOWORD(wParam),lParam);
00194 break;
00195 case WM_PAINT:
00196 hDC = BeginPaint(hWnd, &ps);
00197 AppPaint(hWnd,
00198 hDC,
00199 GetScrollPos(hWnd,SB_HORZ),
00200 GetScrollPos(hWnd,SB_VERT) );
00201 EndPaint(hWnd, &ps);
00202 break ;
00203 case WM_QUERYNEWPALETTE:{
00204 HDC hDC;
00205 HPALETTE hpalT;
00206 if(hpalCurrent == NULL)break;
00207 hDC=GetDC(hWnd);
00208 hpalT = SelectPalette(hDC,hpalCurrent,FALSE);
00209 if(RealizePalette (hDC) > 0)InvalidateRect (hWnd, (LPRECT) (NULL), 1);
00210 SelectPalette(hDC,hpalT,FALSE);
00211 ReleaseDC(hWnd,hDC);
00212 return TRUE;
00213 }
00214 case WM_PALETTECHANGED:
00215 if(hpalCurrent == NULL)break;
00216 if ((HWND)wParam != hWnd ){
00217 HDC hDC;
00218 HPALETTE hpalT;
00219 hDC=GetDC(hWnd);
00220 hpalT = SelectPalette(hDC,hpalCurrent,FALSE);
00221 if(RealizePalette (hDC) > 0)InvalidateRect (hWnd, (LPRECT) (NULL), 1);
00222 SelectPalette(hDC,hpalT,FALSE);
00223 ReleaseDC(hWnd,hDC);
00224 }
00225 break;
00226 case WM_SIZE:
00227 SetScrollRanges(hWnd);
00228 break;
00229 case WM_KEYDOWN:
00230 switch (wParam) {
00231 case VK_UP: PostMessage (hWnd, WM_VSCROLL, SB_LINEUP, 0L); break;
00232 case VK_DOWN: PostMessage (hWnd, WM_VSCROLL, SB_LINEDOWN, 0L); break;
00233 case VK_PRIOR: PostMessage (hWnd, WM_VSCROLL, SB_PAGEUP, 0L); break;
00234 case VK_NEXT: PostMessage (hWnd, WM_VSCROLL, SB_PAGEDOWN, 0L); break;
00235 case VK_HOME: PostMessage (hWnd, WM_HSCROLL, SB_PAGEUP, 0L); break;
00236 case VK_END: PostMessage (hWnd, WM_HSCROLL, SB_PAGEDOWN, 0L); break;
00237 case VK_LEFT: PostMessage (hWnd, WM_HSCROLL, SB_LINEUP, 0L); break;
00238 case VK_RIGHT: PostMessage (hWnd, WM_HSCROLL, SB_LINEDOWN, 0L); break;
00239 }
00240 break;
00241 case WM_KEYUP:
00242 switch (wParam) {
00243 case VK_UP:
00244 case VK_DOWN:
00245 case VK_PRIOR:
00246 case VK_NEXT:
00247 PostMessage (hWnd, WM_VSCROLL, SB_ENDSCROLL, 0L);
00248 break;
00249 case VK_HOME:
00250 case VK_END:
00251 case VK_LEFT:
00252 case VK_RIGHT:
00253 PostMessage (hWnd, WM_HSCROLL, SB_ENDSCROLL, 0L);
00254 break;
00255 }
00256 break;
00257 case WM_VSCROLL:
00258
00259 GetScrollRange (hWnd, SB_VERT, &iMin, &iMax);
00260 iPos = GetScrollPos (hWnd, SB_VERT);
00261 GetClientRect (hWnd, &rc);
00262 switch (LOWORD(wParam)) {
00263 case SB_LINEDOWN: dn = rc.bottom / 16 + 1; break;
00264 case SB_LINEUP: dn = -rc.bottom / 16 + 1; break;
00265 case SB_PAGEDOWN: dn = rc.bottom / 2 + 1; break;
00266 case SB_PAGEUP: dn = -rc.bottom / 2 + 1; break;
00267 case SB_THUMBTRACK:
00268 case SB_THUMBPOSITION: dn = HIWORD(wParam)-iPos; break;
00269 default: dn = 0;
00270 }
00271
00272 if ((dn = BOUND (iPos + dn, iMin, iMax) - iPos) != 0) {
00273 ScrollWindow(hWnd, 0, -dn, NULL, NULL);
00274 SetScrollPos(hWnd, SB_VERT, iPos + dn, TRUE);
00275 }
00276 break;
00277 case WM_HSCROLL:
00278
00279 GetScrollRange(hWnd, SB_HORZ, &iMin, &iMax);
00280 iPos = GetScrollPos(hWnd, SB_HORZ);
00281 GetClientRect (hWnd, &rc);
00282 switch (LOWORD(wParam)) {
00283 case SB_LINEDOWN: dn = rc.right / 16 + 1; break;
00284 case SB_LINEUP: dn = -rc.right / 16 + 1; break;
00285 case SB_PAGEDOWN: dn = rc.right / 2 + 1; break;
00286 case SB_PAGEUP: dn = -rc.right / 2 + 1; break;
00287 case SB_THUMBTRACK:
00288 case SB_THUMBPOSITION: dn = HIWORD(wParam) - iPos; break;
00289 default: dn = 0;
00290 }
00291
00292 if ((dn = BOUND (iPos + dn, iMin, iMax) - iPos) != 0) {
00293 ScrollWindow (hWnd, -dn, 0, NULL, NULL);
00294 SetScrollPos (hWnd, SB_HORZ, iPos + dn, TRUE);
00295 }
00296 break;
00297 default:
00298 return DefWindowProc (hWnd, iMessage, wParam, lParam) ;
00299 }
00300 return 0L ;
00301 }
00302
00303 BOOL MenuCommand (HWND hWnd, WORD id, LONG lparam){
00304 int i;
00305 char lpMessage[MAXTEXT],lpCaption[64];
00306 switch (id) {
00307 case IDM_ABOUT:
00308 MessageBox(hWnd," "
00309 ABOUT_VERSION
00310 " ",
00311 "About OpenFX Viewer..",MB_OK);
00312 break;
00313 case IDM_DISPLAY:
00314 LoadString(hInst,IDS_DISPLAY,lpCaption,64);
00315 if (DisplayWidth==640)
00316 LoadString(hInst,IDS_640,lpMessage,MAXTEXT);
00317 else if(DisplayWidth==800)
00318 LoadString(hInst,IDS_800,lpMessage,MAXTEXT);
00319 else if(DisplayWidth==1024)
00320 LoadString(hInst,IDS_1024,lpMessage,MAXTEXT);
00321 else
00322 LoadString(hInst,IDS_CUSTOM,lpMessage,MAXTEXT);
00323 MessageBox(GetFocus(),lpMessage,lpCaption,MB_OK);
00324 break;
00325 case IDM_COLOURS:
00326 LoadString(hInst,IDS_COLOUR,lpCaption,64);
00327 if(DisplayBits < 8)
00328 LoadString(hInst,IDS_COLOUR16,lpMessage,MAXTEXT);
00329 else if(DisplayBits==8)
00330 LoadString(hInst,IDS_COLOUR256,lpMessage,MAXTEXT);
00331 else if(DisplayBits==16)
00332 LoadString(hInst,IDS_COLOUR65,lpMessage,MAXTEXT);
00333 else if(DisplayBits==24)
00334 LoadString(hInst,IDS_COLOUR16M,lpMessage,MAXTEXT);
00335 else LoadString(hInst,IDS_CUSTOMC,lpMessage,MAXTEXT);
00336 MessageBox(GetFocus(),lpMessage,lpCaption,MB_OK);
00337 break;
00338 case IDM_OPEN: {
00339 OPENFILENAME ofn;
00340 char szTitle[60]="File to View",szFilter[256];
00341 from_renderer=0;
00342 CurrentDirectory[0]='\0';
00343 CurrentFile[0]='\0';
00344 GetModuleFileName(hInst,CurrentDirFile,255);
00345 *FileInPath(CurrentDirFile) = '\0';
00346 GetPrivateProfileString(IniSection,"LASTFILE","*.*",
00347 CurrentFile,sizeof(CurrentFile),IniFilename);
00348 GetPrivateProfileString(IniSection,"LASTPATH",CurrentDirFile,
00349 CurrentDirectory,sizeof(CurrentDirectory),IniFilename);
00350 if(CurrentDirectory[0] != 0)SetCurrentDirectory(CurrentDirectory);
00351 file_format=GetPrivateProfileInt(IniSection,"LASTTYPE",file_format,IniFilename);
00352 strcpy(CurrentDirFile,CurrentDirectory);
00353 strcat(CurrentDirFile,CurrentFile);
00354 strcpy(szFilter,
00355 "All file formats|*.bmp;*.gif;*.tga;*;*.jpg;*.tif;*.png|"
00356 "(*.GIF)|*.gif|"
00357 "(*.TGA)|*.tga|"
00358 "(*.BMP)|*.bmp|"
00359 "(*.TIF)|*.tif|"
00360 "(*.JPG)|*.jpg|"
00361 "(*.PNG)|*.png|");
00362 i=0; while(szFilter[i] != '\0'){
00363 if(szFilter[i] == '|')szFilter[i]='\0';
00364 i++;
00365 }
00366 memset(&ofn,0,sizeof(OPENFILENAME));
00367 ofn.lStructSize=sizeof(OPENFILENAME);
00368 ofn.hwndOwner=hWnd;
00369 ofn.lpstrFilter=szFilter;
00370 if (file_format == FI_GIF)ofn.nFilterIndex=1;
00371 else if(file_format == FI_TGA)ofn.nFilterIndex=2;
00372
00373 else if(file_format == FI_DIB)ofn.nFilterIndex=4;
00374 else if(file_format == FI_TIF)ofn.nFilterIndex=5;
00375 else if(file_format == FI_JPG)ofn.nFilterIndex=6;
00376 else if(file_format == FI_JPG)ofn.nFilterIndex=6;
00377 else if(file_format == FI_PNG)ofn.nFilterIndex=7;
00378 ofn.lpstrFile=CurrentDirFile;
00379 ofn.nMaxFile=sizeof(CurrentDirFile);
00380 ofn.lpstrFileTitle=CurrentFile;
00381 ofn.nMaxFileTitle=sizeof(CurrentFile);
00382 ofn.lpstrInitialDir=CurrentDirectory;
00383 ofn.lpstrTitle=szTitle;
00384 ofn.Flags=OFN_HIDEREADONLY|OFN_PATHMUSTEXIST|OFN_FILEMUSTEXIST;
00385 if(GetOpenFileName(&ofn)){
00386 file_format=identify_file_format();
00387 WritePrivateProfileString(IniSection,"LASTFILE",CurrentFile,IniFilename);
00388 if(FileInPath(CurrentDirFile) != NULL)*FileInPath(CurrentDirFile)='\0';
00389 WritePrivateProfileString(IniSection,"LASTPATH",CurrentDirFile,IniFilename);
00390 sprintf(lpCaption,"%ld",file_format);
00391 WritePrivateProfileString(IniSection,"LASTTYPE",lpCaption,IniFilename);
00392 PostMessage(hWnd,WM_COMMAND,(WPARAM)IDM_DRAWIT,0);
00393 }
00394 break;
00395 }
00396 case IDM_SHOWMAP:
00397 GetPrivateProfileString(IniSection,"MAPFILE","*.*",
00398 CurrentFile,sizeof(CurrentFile),IniFilename);
00399 SendMessage(hWnd,WM_COMMAND,IDM_DRAWIT,0);
00400 break;
00401 case IDM_SHOWLAST:
00402 if(lparam == 1)from_renderer=1;
00403 else from_renderer=0;
00404 CurrentDirectory[0]='\0';
00405 CurrentFile[0]='\0';
00406 GetModuleFileName(hInst,CurrentDirFile,255);
00407 *FileInPath(CurrentDirFile) = '\0';
00408 GetPrivateProfileString(IniSection,"FILE","*.*",
00409 CurrentFile,sizeof(CurrentFile),IniFilename);
00410 GetPrivateProfileString(IniSection,"PATH",CurrentDirFile,
00411 CurrentDirectory,sizeof(CurrentDirectory),IniFilename);
00412 if(CurrentDirectory[0] != 0 && CurrentFile[0] != 0){
00413 strcpy(CurrentDirFile,CurrentDirectory);
00414 strcat(CurrentDirFile,CurrentFile);
00415 strcpy(CurrentFile,CurrentDirFile);
00416 }
00417 file_format=GetPrivateProfileInt(IniSection,"TYPE",file_format,IniFilename);
00418 case IDM_DRAWIT:
00419 StartWait();
00420 file_format=identify_file_format();
00421 switch(file_format){
00422 case FI_GIF:
00423 if(gifview(hWnd))InvalidateRect (hWnd, NULL, FALSE);
00424 break;
00425 case FI_TGA:
00426 if(tgaview(hWnd))InvalidateRect (hWnd, NULL, FALSE);
00427 break;
00428
00429
00430
00431 case FI_DIB:
00432 if(dibview(hWnd))InvalidateRect (hWnd, NULL, FALSE);
00433 break;
00434 case FI_TIF:
00435 if(tifview(hWnd))InvalidateRect (hWnd, NULL, FALSE);
00436 break;
00437 case FI_JPG:
00438 if(jpgview(hWnd))InvalidateRect (hWnd, NULL, FALSE);
00439 break;
00440 case FI_PNG:
00441 if(pngview(hWnd))InvalidateRect (hWnd, NULL, FALSE);
00442 break;
00443 default:
00444 break;
00445 }
00446 EndWait();
00447 if(from_renderer){
00448 HWND hRndr;
00449 if((hRndr=FindWindow("OFX:RenderClass",NULL)) != NULL){
00450 SetForegroundWindow(hRndr);
00451 }
00452 from_renderer=0;
00453 }
00454 break;
00455 case IDM_HIDE:
00456 ShowWindow(hWnd,SW_HIDE);
00457 break;
00458 case IDM_EXIT:
00459 PostQuitMessage(0);
00460 break;
00461 default:
00462 break;
00463 }
00464 return TRUE;
00465 }
00466
00467 static void FreeDib(void){
00468 if (hpalCurrent) DeleteObject(hpalCurrent);
00469 if (hbmCurrent) DeleteObject(hbmCurrent);
00470 if(lpBitmapBits != NULL)X__Free((char *)lpBitmapBits);
00471 if(lpBitmapHeader != NULL)X__Free((char *)lpBitmapHeader);
00472 lpBitmapHeader = NULL;
00473 lpBitmapBits = NULL;
00474 hpalCurrent = NULL;
00475 hbmCurrent = NULL;
00476 pRgb = NULL;
00477 }
00478
00479 static int identify_file_format(void){
00480 int ff=FI_DIB;
00481 strupr(CurrentFile);
00482 if (strstr(CurrentFile,".GIF"))ff=FI_GIF;
00483
00484 else if(strstr(CurrentFile,".TGA"))ff=FI_TGA;
00485 else if(strstr(CurrentFile,".DIB") ||
00486 strstr(CurrentFile,".BMP") ||
00487 strstr(CurrentFile,".RLE"))ff=FI_DIB;
00488 else if(strstr(CurrentFile,".TIF"))ff=FI_TIF;
00489 else if(strstr(CurrentFile,".JPG"))ff=FI_JPG;
00490 else if(strstr(CurrentFile,".PNG"))ff=FI_PNG;
00491 return ff;
00492 }
00493
00494 static int ErrMsg(char *sz,...){
00495 char ach[256];
00496 va_list arg_ptr;
00497 va_start(arg_ptr,sz);
00498 vsprintf(ach,sz,arg_ptr);
00499 va_end(arg_ptr);
00500 MessageBox (NULL, ach, NULL, MB_OK|MB_ICONEXCLAMATION|MB_APPLMODAL);
00501 return FALSE;
00502 }
00503
00504 static void PutMsg(char *s){
00505 MessageBox (NULL,s, "Viewer", MB_OK|MB_ICONEXCLAMATION|MB_APPLMODAL);
00506 }
00507
00508 static void LoadErrMsg(int id){
00509 char mes[256];
00510 LoadString(hInst,id,mes,255);
00511 ErrMsg(mes);
00512 }
00513
00514 static void SizeWindow(HWND hWnd){
00515 char Title[120];
00516 RECT Rectangle;
00517 int dx,dy;
00518 POINT pt;
00519 LPBITMAPINFOHEADER bi;
00520 if((bi=(LPBITMAPINFOHEADER)lpBitmapHeader) == NULL)return;
00521 sprintf(Title,
00522 "%s (%s %ldx%ldx%ld)",
00523 "View",
00524 CurrentFile,
00525 (long)x_size,
00526 (long)bi->biHeight,
00527 (long)bi->biBitCount);
00528 SetWindowText(hWnd,Title);
00529 ptSize.x = (WORD)bi->biWidth;
00530 ptSize.y = (WORD)bi->biHeight;
00531 if (IsZoomed(hWnd))SetScrollRanges(hWnd);
00532 else {
00533 Rectangle.left = 0;
00534 Rectangle.top = 0;
00535 Rectangle.right = (WORD)bi->biWidth;
00536 Rectangle.bottom = (WORD)bi->biHeight;
00537 AdjustWindowRect (&Rectangle,fdwStyle,TRUE);
00538 SetWindowPos (hWnd, (HWND)NULL, 0, 0,
00539 Rectangle.right - Rectangle.left + 1,
00540 Rectangle.bottom - Rectangle.top + 1,
00541 SWP_NOMOVE | SWP_NOZORDER);
00542 }
00543 InvalidateRect(hWnd,NULL,TRUE);
00544 }
00545
00546 static void SetScrollRanges(HWND hwnd){
00547 RECT rc;
00548 int iRangeH,iRangeV,i;
00549 static int iSem = 0;
00550 if(!iSem){
00551 iSem++;
00552 GetRealClientRect(hwnd,&rc);
00553 for(i = 0; i < 2; i++){
00554 iRangeV = ptSize.y - rc.bottom;
00555 iRangeH = ptSize.x - rc.right;
00556 if(iRangeH < 0)iRangeH = 0;
00557 if(iRangeV < 0)iRangeV = 0;
00558 if (GetScrollPos(hwnd,SB_VERT) > iRangeV ||
00559 GetScrollPos(hwnd, SB_HORZ) > iRangeH)
00560 InvalidateRect (hwnd, NULL, TRUE);
00561 SetScrollRange(hwnd, SB_VERT, 0, iRangeV, TRUE);
00562 SetScrollRange(hwnd, SB_HORZ, 0, iRangeH, TRUE);
00563 GetClientRect(hwnd, &rc);
00564 }
00565 iSem--;
00566 }
00567 }
00568
00569 static HPALETTE CreateImagePalette(LPBITMAPINFOHEADER lpbi){
00570 LOGPALETTE *pPal;
00571 HPALETTE hpal = NULL;
00572 WORD nNumColors;
00573 BYTE red;
00574 BYTE green;
00575 BYTE blue;
00576 int i;
00577 RGBQUAD *pRgb;
00578 if(lpbi == NULL)return NULL;
00579 if(lpbi->biSize != sizeof(BITMAPINFOHEADER))return NULL;
00580
00581 pRgb = (RGBQUAD *)((LPSTR)lpbi + (WORD)lpbi->biSize);
00582 nNumColors = NumColours(lpbi);
00583 if(nNumColors){
00584 pPal = (LOGPALETTE*)LocalAlloc(LPTR,sizeof(LOGPALETTE) + nNumColors * sizeof(PALETTEENTRY));
00585 if(pPal == NULL)return NULL;
00586 pPal->palNumEntries = nNumColors;
00587 pPal->palVersion = PALVERSION;
00588
00589
00590 for (i = 0; i < nNumColors; i++){
00591 pPal->palPalEntry[i].peRed = pRgb[i].rgbRed;
00592 pPal->palPalEntry[i].peGreen = pRgb[i].rgbGreen;
00593 pPal->palPalEntry[i].peBlue = pRgb[i].rgbBlue;
00594 pPal->palPalEntry[i].peFlags = (BYTE)0;
00595 }
00596 hpal = CreatePalette(pPal);
00597 LocalFree((HANDLE)pPal);
00598 }
00599 else if (lpbi->biBitCount == 24){
00600
00601
00602 nNumColors = MAXPALETTE;
00603 pPal=(LOGPALETTE*)LocalAlloc(LPTR,sizeof(LOGPALETTE) + nNumColors * sizeof(PALETTEENTRY));
00604 if(pPal == NULL)return NULL;
00605 pPal->palNumEntries = nNumColors;
00606 pPal->palVersion = PALVERSION;
00607 red = green = blue = 0;
00608
00609 for (i = 0; i < pPal->palNumEntries; i++){
00610 pPal->palPalEntry[i].peRed = red;
00611 pPal->palPalEntry[i].peGreen = green;
00612 pPal->palPalEntry[i].peBlue = blue;
00613 pPal->palPalEntry[i].peFlags = (BYTE)0;
00614 if (!(red += 32))if (!(green += 32)) blue += 64;
00615 }
00616 hpal = CreatePalette(pPal);
00617 LocalFree((HANDLE)pPal);
00618 }
00619 return hpal;
00620 }
00621
00622 static WORD NumColours(LPBITMAPINFOHEADER lpbi){
00623 WORD bits;
00624 if (lpbi->biClrUsed != 0)return (WORD)lpbi->biClrUsed;
00625 bits = lpbi->biBitCount;
00626 switch (bits){
00627 case 1: return 2;
00628 case 4: return 16;
00629 case 8: return 256;
00630 default: return 0;
00631 }
00632 }
00633
00634 static void GetRealClientRect(HWND hwnd, PRECT lprc){
00635
00636 DWORD dwStyle;
00637 dwStyle = GetWindowLong (hwnd, GWL_STYLE);
00638 GetClientRect (hwnd,lprc);
00639 if (dwStyle & WS_HSCROLL)lprc->bottom += GetSystemMetrics(SM_CYHSCROLL);
00640 if (dwStyle & WS_VSCROLL)lprc->right += GetSystemMetrics(SM_CXVSCROLL);
00641 }
00642
00643 static void AppPaint(HWND hWnd,HDC hDC,int x,int y){
00644 HPALETTE hpalT;
00645 POINT Origin;
00646 HDC hDCbits;
00647 BITMAP bm;
00648 SetWindowOrgEx(hDC,x,y,&Origin);
00649 SetBkMode (hDC,TRANSPARENT);
00650 if(hpalCurrent != NULL){
00651 hpalT = SelectPalette(hDC,hpalCurrent,FALSE);
00652 RealizePalette (hDC);
00653 if(hbmCurrent != NULL){
00654 hDCbits = CreateCompatibleDC(hDC);
00655 GetObject(hbmCurrent,sizeof(BITMAP),(LPSTR)&bm);
00656 SelectObject(hDCbits,hbmCurrent);
00657 BitBlt(hDC,0,0,bm.bmWidth,bm.bmHeight,hDCbits,0,0,SRCCOPY);
00658 DeleteDC(hDCbits);
00659 }
00660 else {
00661 if(lpBitmapHeader != NULL && lpBitmapBits != NULL){
00662 SetDIBitsToDevice(hDC,
00663 0,0,
00664 (WORD)((LPBITMAPINFOHEADER)lpBitmapHeader)->biWidth,
00665 (WORD)((LPBITMAPINFOHEADER)lpBitmapHeader)->biHeight,
00666 0,0,
00667 0,
00668 (WORD)((LPBITMAPINFOHEADER)lpBitmapHeader)->biHeight,
00669 lpBitmapBits,
00670 (LPBITMAPINFO)lpBitmapHeader,
00671 DIB_RGB_COLORS);
00672 }
00673 }
00674 SelectPalette(hDC,hpalT,FALSE);
00675 }
00676 }
00677
00678 static HBITMAP BitmapFromDib(LPSTR lpHeader,LPSTR lpBits,HPALETTE hpal){
00679 HDC hdc;
00680 HBITMAP hbm;
00681 HPALETTE hpalT;
00682 if (lpHeader == NULL || lpBits == NULL)return NULL;
00683 hdc = GetDC(NULL);
00684 if(hpal != NULL){
00685 hpalT = SelectPalette(hdc,hpal,FALSE);
00686 RealizePalette(hdc);
00687 }
00688 hbm = CreateDIBitmap(hdc,
00689 (LPBITMAPINFOHEADER)lpHeader,
00690 (LONG)CBM_INIT,
00691 lpBits,
00692 (LPBITMAPINFO)lpHeader,
00693 DIB_RGB_COLORS );
00694 if(hpalCurrent)SelectPalette(hdc,hpalT,FALSE);
00695 ReleaseDC(NULL,hdc);
00696 return hbm;
00697 }
00698
00699 #define DibNumColors(bmih) (bmih.biClrUsed == 0 && bmih.biBitCount <= 8 \
00700 ? (int)(1 << (int)bmih.biBitCount) \
00701 : (int)bmih.biClrUsed)
00702
00703 static int dibview(HWND hWnd){
00704 char temp[256];
00705 HDC hdc;
00706 HANDLE hfbm;
00707 BITMAPFILEHEADER bmfh;
00708 DWORD dwRead;
00709 BITMAPINFOHEADER bmih;
00710 LPBITMAPINFOHEADER lpbi;
00711 LPBITMAPINFO lpinfo;
00712 long imagesize,nc;
00713 FreeDib();
00714 strcpy(temp,CurrentFile);
00715 hfbm=CreateFile(temp,GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_EXISTING,
00716 FILE_ATTRIBUTE_READONLY,(HANDLE)NULL);
00717 ReadFile(hfbm,&bmfh,sizeof(BITMAPFILEHEADER),&dwRead,(LPOVERLAPPED)NULL);
00718 ReadFile(hfbm,&bmih,sizeof(BITMAPINFOHEADER),&dwRead,(LPOVERLAPPED)NULL);
00719 nc=DibNumColors(bmih);
00720 lpBitmapHeader = (LPSTR)X__Malloc((long)sizeof(BITMAPINFOHEADER)+
00721 nc*sizeof(RGBQUAD));
00722 if(lpBitmapHeader == NULL)return 0;
00723 lpbi=(LPBITMAPINFOHEADER)lpBitmapHeader;
00724 lpinfo=(LPBITMAPINFO)lpBitmapHeader;
00725 lpbi->biSize=bmih.biSize;
00726 x_size=lpbi->biWidth=bmih.biWidth;
00727 lpbi->biHeight=bmih.biHeight;
00728 lpbi->biPlanes=bmih.biPlanes;
00729 lpbi->biBitCount=bmih.biBitCount;
00730 lpbi->biCompression=bmih.biCompression;
00731 lpbi->biSizeImage=bmih.biSizeImage;
00732 lpbi->biXPelsPerMeter=bmih.biXPelsPerMeter;
00733 lpbi->biYPelsPerMeter=bmih.biYPelsPerMeter;
00734 lpbi->biClrUsed=bmih.biClrUsed;
00735 lpbi->biClrImportant=bmih.biClrImportant;
00736 if(nc > 0)ReadFile(hfbm,lpinfo->bmiColors,nc*sizeof(RGBQUAD),
00737 &dwRead,(LPOVERLAPPED)NULL);
00738 hpalCurrent=CreateImagePalette(lpbi);
00739 imagesize=bmfh.bfSize-bmfh.bfOffBits;
00740 lpBitmapBits=(LPSTR)X__Malloc(imagesize);
00741 if(lpBitmapBits == NULL){
00742 FreeDib();
00743 return 0;
00744 }
00745 memset(lpBitmapBits,0,imagesize);
00746 pixels=lpBitmapBits;
00747 ReadFile(hfbm,lpBitmapBits,imagesize,&dwRead,(LPOVERLAPPED)NULL);
00748 if(!CloseHandle(hfbm)){
00749 MessageBeep(MB_OK);
00750 MessageBox(NULL,"Bad close",NULL,MB_OK);
00751 }
00752 hbmCurrent=BitmapFromDib(lpBitmapHeader,lpBitmapBits,hpalCurrent);
00753 if(hbmCurrent == NULL)LoadErrMsg(IDX_ERR_NOBITMAP);
00754 SizeWindow(hWnd);
00755 return 1;
00756 }
00757
00758 #include "view_gif.c"
00759 #include "view_tga.c"
00760 #include "view_tif.c"
00761 #include "view_jpg.c"
00762 #include "view_png.c"
00763
00764
00765
00766 int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
00767 LPSTR lpCmdLine, int nCmdShow){
00768 HWND hWndPrev;
00769 hWndPrev = FindWindow(szViewClass,NULL);
00770 if (hWndPrev != NULL){
00771 SetForegroundWindow(hWndPrev);
00772 BringWindowToTop(hWndPrev);
00773 ShowWindow (hWndPrev,SW_SHOW);
00774 return 32;
00775 }
00776 if(hPrevInstance != NULL)return FALSE;
00777
00778
00779 {
00780 FILE *fini=NULL; int ix;
00781 char TempPath[256];
00782 GetModuleFileName(hInstance,IniFilename,256);
00783 *FileInPath(IniFilename) = '\0';
00784 strcpy(TempPath,IniFilename);
00785 strcat(IniFilename,"OPENFX_.CFG");
00786 if((fini=fopen(IniFilename,"r")) != NULL){
00787 fscanf(fini,"%ld",&ix);
00788 strcpy(TempPath,"X");
00789 fscanf(fini," %[^\n]",TempPath);
00790 if(ix > 1){
00791 fscanf(fini," %[^\n]",IniFilename);
00792 }
00793 else *FileInPath(IniFilename) = '\0';
00794 fclose(fini);
00795 }
00796 else {
00797 char *pE;
00798 pE=R_GetEnv("TEMP");
00799 if(pE != NULL){
00800 strcpy(TempPath,pE); strcat(TempPath,"\\");
00801 strcpy(IniFilename,TempPath);
00802 *FileInPath(TempPath) = '\0';
00803 }
00804 *FileInPath(IniFilename) = '\0';
00805 }
00806 strcat(IniFilename,"OPENFX_.INI");
00807 }
00808
00809 return Viewer(hInstance);
00810 }