www.pudn.com > 3D_OnlineGame_Humen.rar > misc.cpp
/* * Copyright (C) 1998 Microsoft Corporation. All Rights Reserved. * * File: misc.c * * Miscellaneous functions not involving DD and D3D. Part of D3DApp. * * D3DApp is a collection of helper functions for Direct3D applications. * D3DApp consists of the following files: * d3dapp.h Main D3DApp header to be included by application * d3dappi.h Internal header * d3dapp.c D3DApp functions seen by application. * ddcalls.c All calls to DirectDraw objects except textures * d3dcalls.c All calls to Direct3D objects except textures * texture.c Texture loading and managing texture list * misc.c Miscellaneous calls */ #include "stdafx.h" #include "XMudClient.h" #include "d3dappi.h" #include#include "MyDInput.h" #include "MenuCreateNew.h" /***************************************************************************/ /* Setting Defaults */ /***************************************************************************/ /* * D3DAppISetDefaults * Set all the global variables to their default values. Do not reset the * image files. */ void D3DAppISetDefaults(void) { int n; char backup[D3DAPP_MAXTEXTURES][50]; n = d3dappi.NumTextures; memcpy(&backup[0][0], &d3dappi.ImageFile[0][0], 50 * D3DAPP_MAXTEXTURES); ZEROMEM(d3dappi); memcpy(&d3dappi.ImageFile[0][0], &backup[0][0], 50 * D3DAPP_MAXTEXTURES); d3dappi.NumTextures = n; d3dappi.bAppActive = TRUE; ZEROMEM(d3dapprs); d3dapprs.bZBufferOn = TRUE; d3dapprs.bPerspCorrect = TRUE; //FALSE; d3dapprs.ShadeMode = D3DSHADE_FLAT; //D3DSHADE_GOURAUD; d3dapprs.TextureFilter = D3DFILTER_NEAREST; d3dapprs.TextureBlend = D3DTBLEND_MODULATE; d3dapprs.FillMode = D3DFILL_SOLID; d3dapprs.bDithering = FALSE; d3dapprs.bSpecular = TRUE; d3dapprs.bAntialiasing = FALSE; d3dapprs.bFogEnabled = FALSE; d3dapprs.FogColor = RGB_MAKE(255, 255, 255); d3dapprs.FogMode = D3DFOG_LINEAR; d3dapprs.FogStart = D3DVAL(6.0); d3dapprs.FogEnd = D3DVAL(11.0); lpClipper = NULL; lpPalette = NULL; bPrimaryPalettized = FALSE; bPaletteActivate = FALSE; bIgnoreWM_SIZE = FALSE; ZEROMEM(ppe); ZEROMEM(Originalppe); LastError = DD_OK; ZEROMEM(LastErrorString); D3DDeviceDestroyCallback = NULL; D3DDeviceDestroyCallbackContext = NULL; D3DDeviceCreateCallback = NULL; D3DDeviceCreateCallbackContext = NULL; } BOOL D3DAppICallDeviceDestroyCallback(void) { if (D3DDeviceDestroyCallback) { if (CallbackRefCount) { --CallbackRefCount; return (D3DDeviceDestroyCallback)(D3DDeviceDestroyCallbackContext); } } return TRUE; } BOOL D3DAppICallDeviceCreateCallback(int w, int h) { if (D3DDeviceCreateCallback) { ++CallbackRefCount; return (D3DDeviceCreateCallback)(w,h,&d3dappi.lpD3DViewport,D3DDeviceCreateCallbackContext); } return TRUE; } /***************************************************************************/ /* Choosing and verifying the driver and display mode */ /***************************************************************************/ /* * D3DAppIPickDriver * Choose a driver from the list of available drivers which can render to one * of the given depths. Hardware is prefered. Mono-lighting drivers are * prefered over RGB. */ BOOL D3DAppIPickDriver(int* driver, DWORD depths) { int i, j; j = 0; for (i = 0; i < d3dappi.NumDrivers; i++) { if (d3dappi.Driver[i].Desc.dwDeviceRenderBitDepth & depths) break; } if (i >= d3dappi.NumDrivers) { *driver = D3DAPP_BOGUS; return TRUE; } j = i; for (i = 0; i < d3dappi.NumDrivers; i++) { if (d3dappi.Driver[i].Desc.dwDeviceRenderBitDepth & depths) { if (d3dappi.Driver[i].bIsHardware && !d3dappi.Driver[j].bIsHardware) { j = i; } else if (d3dappi.Driver[i].bIsHardware == d3dappi.Driver[j].bIsHardware) { if (d3dappi.Driver[i].Desc.dcmColorModel & D3DCOLOR_MONO && !(d3dappi.Driver[j].Desc.dcmColorModel & D3DCOLOR_MONO)) { j = i; } } } } if (j >= d3dappi.NumDrivers) *driver = D3DAPP_BOGUS; else *driver = j; return TRUE; } BOOL D3DAppIFilterDisplayModes(int driver) { int i; DWORD depths = d3dappi.Driver[driver].Desc.dwDeviceRenderBitDepth; for (i = 0; i < d3dappi.NumModes; i++) { d3dappi.Mode[i].bThisDriverCanDo = FALSE; if (!(D3DAppIBPPToDDBD(d3dappi.Mode[i].bpp) & depths)) continue; d3dappi.Mode[i].bThisDriverCanDo = TRUE; } d3dappi.ThisMode.bThisDriverCanDo = d3dappi.Mode[d3dappi.CurrMode].bThisDriverCanDo; return TRUE; } BOOL D3DAppIPickDisplayMode(int *mode, DWORD depths) { int i, j; for (i = 0; i < d3dappi.NumModes; i++) { if (D3DAppIBPPToDDBD(d3dappi.Mode[i].bpp) & depths) break; } j = i; for (; i < d3dappi.NumModes; i++) { if (!(D3DAppIBPPToDDBD(d3dappi.Mode[i].bpp) & depths)) continue; if (d3dappi.Mode[i].w == DEFULTWND_WIDTH && d3dappi.Mode[i].h == DEFULTWND_HEIGHT && d3dappi.Mode[i].bpp == 16) { j = i; break; } } if (j >= d3dappi.NumModes) *mode = D3DAPP_BOGUS; else *mode = j; return TRUE; } /* * D3DAppIVerifyDriverAndMode * Verifies the selected driver and mode combination. If the driver is * specified, the mode will be changed to accomodate the driver if it's not * compatible. If the driver is not specified, one will be selected which is * compatible with the specified mode. If neither are specified, a suitable * pair will be returned. */ BOOL D3DAppIVerifyDriverAndMode(int* lpdriver, int* lpmode) { DWORD depths; int driver, mode, i; driver = *lpdriver; mode = *lpmode; if (mode == D3DAPP_USEWINDOW && !d3dappi.bIsPrimary) { D3DAppISetErrorString("Cannot render to a window when the DirectDraw device is not the primary.\n"); goto exit_with_error; } /* * If I've been ask to choose a driver, choose one which is compatible * with the specified mode. */ if (driver == D3DAPP_YOUDECIDE) { if (mode == D3DAPP_USEWINDOW) { /* * I must find a driver for this display depth */ depths = D3DAppIBPPToDDBD(d3dappi.WindowsDisplay.bpp); ATTEMPT(D3DAppIPickDriver(&driver, depths)); if (driver == D3DAPP_BOGUS) { D3DAppISetErrorString("Cannot find a D3D device driver which is compatible with the current display depth.\n"); goto exit_with_error; } /* * I don't need to go through the mode selection since I've * verified it here */ goto ret_ok; } else if (mode == D3DAPP_YOUDECIDE) { /* * I'm free to choose any driver which can use even one * supported depth */ if (d3dappi.bIsPrimary) depths = D3DAppIBPPToDDBD(d3dappi.WindowsDisplay.bpp); else depths = 0; for (i = 0; i < d3dappi.NumModes; i++) depths |= D3DAppIBPPToDDBD(d3dappi.Mode[i].bpp); ATTEMPT(D3DAppIPickDriver(&driver, depths)); if (driver == D3DAPP_BOGUS) { D3DAppISetErrorString("Cannot find a D3D device driver which is compatible with the current display depth or any supported fullscreen mode.\n"); goto exit_with_error; } /* * The mode will be chosen in the next section */ } else { /* * Must pick a driver which uses the given mode depth */ ATTEMPT(D3DAppIPickDriver(&driver, D3DAppIBPPToDDBD(d3dappi.Mode[mode].bpp))); if (driver == D3DAPP_BOGUS) { D3DAppISetErrorString("Cannot find a D3D device driver which is compatible with the specified fullscreen mode.\n"); goto exit_with_error; } /* * I don't need to go through the mode selection since I've * verified it here */ goto ret_ok; } } /* * At this stage, I have a driver I want to match the mode to. */ if (mode == D3DAPP_YOUDECIDE) { /* * If it's my choice, I prefer windowed over fullscreen */ if (d3dappi.bIsPrimary) { if (D3DAppIBPPToDDBD(d3dappi.WindowsDisplay.bpp) & d3dappi.Driver[driver].Desc.dwDeviceRenderBitDepth) { mode = D3DAPP_USEWINDOW; goto ret_ok; } } /* * Either this is not a primary DD device or the driver cannot use * the Windows display depth */ ATTEMPT(D3DAppIPickDisplayMode(&mode, d3dappi.Driver[driver].Desc.dwDeviceRenderBitDepth)); if (mode == D3DAPP_BOGUS) { D3DAppISetErrorString("The selected D3D device driver is not compatible with the current display depth or any supported fullscreen modes.\n"); goto exit_with_error; } goto ret_ok; } else if (mode == D3DAPP_USEWINDOW) { /* * Check to see if this driver can use the Windows display depth */ if (D3DAppIBPPToDDBD(d3dappi.WindowsDisplay.bpp) & d3dappi.Driver[driver].Desc.dwDeviceRenderBitDepth) { goto ret_ok; } else { /* * Since it cannot, call this function again to choose any * display mode which is compatible */ mode = D3DAPP_YOUDECIDE; ATTEMPT(D3DAppIVerifyDriverAndMode(&driver, &mode)); if (driver == D3DAPP_BOGUS) goto exit_with_error; goto ret_ok; } } else { /* * Check to see if this driver can use the specified fullscreen mode */ if (D3DAppIBPPToDDBD(d3dappi.Mode[mode].bpp) & d3dappi.Driver[driver].Desc.dwDeviceRenderBitDepth) { goto ret_ok; } else { /* * Since it cannot, call this function again to choose any * display mode which is compatible */ mode = D3DAPP_YOUDECIDE; ATTEMPT(D3DAppIVerifyDriverAndMode(&driver, &mode)); if (driver == D3DAPP_BOGUS) goto exit_with_error; goto ret_ok; } } ret_ok: *lpdriver = driver; *lpmode = mode; return TRUE; exit_with_error: return FALSE; } /***************************************************************************/ /* Dirty Rectangle Functions */ /***************************************************************************/ /* * D3DAppIValidateDirtyRects * Set the dirty rectangles for the front and back buffers to the entire * client size. */ void D3DAppIValidateDirtyRects(void) { NumDirtyClientRects = 1; NumDirtyBackRects = 1; NumDirtyZRects = 1; SetRect((LPRECT)&DirtyClient[0], 0, 0, d3dappi.szClient.cx, d3dappi.szClient.cy); SetRect((LPRECT)&DirtyBack[0], 0, 0, d3dappi.szClient.cx, d3dappi.szClient.cy); SetRect((LPRECT)&DirtyZ[0], 0, 0, d3dappi.szClient.cx, d3dappi.szClient.cy); } /* * D3DAppICopyRectList * Copy a list of rectangles to another */ void D3DAppICopyRectList(int* dstnum, LPD3DRECT dst, int srcnum, LPD3DRECT src) { int i; for (i = 0; i < srcnum; i++) dst[i] = src[i]; *dstnum = srcnum; } /* * MERGE macro * Set first rectangle to be the smallest rectangle containing both rects */ #undef MERGE #define MERGE(rc1, rc2) \ do { \ if (rc2.x1 < rc1.x1) rc1.x1 = rc2.x1; \ if (rc2.y1 < rc1.y1) rc1.y1 = rc2.y1; \ if (rc2.x2 > rc1.x2) rc1.x2 = rc2.x2; \ if (rc2.y2 > rc1.y2) rc1.y2 = rc2.y2; \ } while(0) /* * D3DAppIMergeRectLists * Merge two lists of rectangles to create another list of rectangles. The * merged list of rectangles covers all the area of the original two with NO * OVERLAPPING amongst it's rectangles. */ void D3DAppIMergeRectLists(int* dstnum, LPD3DRECT dst, int src1num, LPD3DRECT src1, int src2num, LPD3DRECT src2) { LPD3DRECT rc; int* isvalid; int num, i, j, intersect; rc = (LPD3DRECT)malloc(sizeof(D3DRECT) * D3DAPP_MAXCLEARRECTS * 2); memset(rc, 0, sizeof(D3DRECT) * D3DAPP_MAXCLEARRECTS * 2); isvalid = (int*)malloc(sizeof(int) * D3DAPP_MAXCLEARRECTS * 2); memset(isvalid, 0, sizeof(int) * D3DAPP_MAXCLEARRECTS * 2); for (i = 0; i < src1num; i++) { memcpy(&rc[i], &src1[i], sizeof(D3DRECT)); if ((rc[i].x1 == 0 && rc[i].x2 == 0) || (rc[i].y1 == 0 && rc[i].y2 == 0)) isvalid[i] = 0; else if (rc[i].x1 <= rc[i].x2 && rc[i].y1 <= rc[i].y2) isvalid[i] = 1; else isvalid[i] = 0; } for (i = 0; i < src2num; i++) { memcpy(&rc[i + src1num], &src2[i], sizeof(D3DRECT)); if (rc[i + src1num].x1 <= rc[i + src1num].x2 && rc[i + src1num].y1 <= rc[i + src1num].y2) isvalid[i + src1num] = 1; else isvalid[i + src1num] = 0; } num = src1num + src2num; for (i = 0; i < num - 1; i++) { if (!isvalid[i]) continue; j = i + 1; do { intersect = 0; for (; j < num; j++) { if (j != i && isvalid[j]) { if (rc[i].x1 < rc[j].x1) { if (rc[i].x2 < rc[j].x1) continue; } else { if (rc[j].x2 < rc[i].x1) continue; } if (rc[i].y1 < rc[j].y1) { if (rc[i].y2 < rc[j].y1) continue; } else { if (rc[j].y2 < rc[i].y1) continue; } MERGE(rc[i], rc[j]); isvalid[j] = 0; j = 0; intersect = 1; break; } } } while(intersect); } for (i = 0, j = 0; i < num; i++) { if (isvalid[i]) ++j; } if (j > D3DAPP_MAXCLEARRECTS) { for (i = 0; i < num; i++) if (isvalid[i]) break; if (i < num) { *dstnum = 1; dst[0] = rc[i]; for (; i < num; i++) { if (isvalid[i]) { MERGE(dst[0], rc[i]); } } } else { *dstnum = 0; } } else { for (i = 0, j = 0; i < num; i++) { if (isvalid[i]) { memcpy(&dst[j], &rc[i], sizeof(D3DRECT)); ++j; } } *dstnum = j; } free(rc); free(isvalid); } /***************************************************************************/ /* Getting and Setting Window Attribs */ /***************************************************************************/ /* * D3DAppISetClientSize * Set the client size of the given window. A WM_SIZE message is generated, * but ignored. */ void D3DAppISetClientSize(HWND hwnd, int w, int h, BOOL bReturnFromFullscreen) { RECT rc; bIgnoreWM_SIZE = TRUE; if (bReturnFromFullscreen) { SetRect(&rc, 0, 0, w, h); AdjustWindowRectEx(&rc, GetWindowLong(hwnd, GWL_STYLE), GetMenu(hwnd) != NULL, GetWindowLong(hwnd, GWL_EXSTYLE)); SetWindowPos(hwnd, NULL, 0, 0, rc.right-rc.left, rc.bottom-rc.top, SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE); SetWindowPos(hwnd, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE); } else { /* * This is the only way to set the client size correctly if the menu * is stacked, so do it unless we are returning from a fullscreen * mode. */ SendMessage(hwnd, WM_SIZE, SIZE_RESTORED, (w + h) << 16); GetWindowRect(hwnd, &rc); SetWindowPos(hwnd, NULL, 0, 0, rc.right-rc.left, rc.bottom-rc.top, SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE); SetWindowPos(hwnd, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE); } bIgnoreWM_SIZE = FALSE; d3dappi.pClientOnPrimary.x = d3dappi.pClientOnPrimary.y = 0; ClientToScreen(hwnd, &d3dappi.pClientOnPrimary); d3dappi.szClient.cx = w; d3dappi.szClient.cy = h; } void D3DAppIGetClientWin(HWND hwnd) { RECT rc; if (!d3dappi.bFullscreen) { d3dappi.pClientOnPrimary.x = d3dappi.pClientOnPrimary.y = 0; ClientToScreen(hwnd, &d3dappi.pClientOnPrimary); GetClientRect(hwnd, &rc); d3dappi.szClient.cx = rc.right; d3dappi.szClient.cy = rc.bottom; } else { /* * In the fullscreen case, we must be careful because if the window * frame has been drawn, the client size has shrunk and this can * cause problems, so it's best to report the entire screen. */ d3dappi.pClientOnPrimary.x = d3dappi.pClientOnPrimary.y = 0; d3dappi.szClient.cx = d3dappi.ThisMode.w; d3dappi.szClient.cy = d3dappi.ThisMode.h; } } /***************************************************************************/ /* Error reporting */ /***************************************************************************/ /* * D3DAppISetErrorString * Set the global variable which records the last error string. */ void D3DAppISetErrorString( LPSTR fmt, ... ) { char buff[256]; va_list args; buff[0] = 0; va_start(args, fmt); wvsprintf(&buff[0], fmt, args); va_end(args); lstrcat(buff, "\r\n"); lstrcpy(LastErrorString, buff); } /* dpf * Debug printf. Very useful for fullscreen exclusive mode or when surfaces * are in video memory. */ void __cdecl dpf( LPSTR fmt, ... ) { char buff[256]; va_list args; lstrcpy(buff, "D3DApp: "); va_start(args, fmt); wvsprintf(&buff[lstrlen(buff)], fmt, args); va_end(args); lstrcat(buff, "\r\n"); OutputDebugString(buff); } void DelayTime(DWORD delay) { DWORD LastTickCount=timeGetTime(); while(timeGetTime()-LastTickCount sx?fx-sx:sx-fx; dy=fy>sy?fy-sy:sy-fy; hpenNew=CreatePen(PS_SOLID,1,c); hpenOld=(HPEN)SelectObject(hDC,hpenNew); if(dx>dy) { for(i=sy;i<=fy;i++) { MoveToEx(hDC,sx,i,NULL); LineTo(hDC,fx+1,i); } } else { for(i=sx;i<=fx;i++) { MoveToEx(hDC,i,sy,NULL); LineTo(hDC,i,fy+1); } } SelectObject(hDC,hpenOld); DeleteObject(hpenNew); } // ************************************************************************************************ // 畫立體邊框 // ************************************************************************************************ void DrawCubicBox(long sx,long sy,long dx,long dy,long R,long G,long B) { COLORREF H=RGB(R ,G ,B ); COLORREF M=RGB(R/2,G/2,B/2); COLORREF L=RGB(R/4,G/4,B/4); DrawLINE(sx ,sy ,dx ,sy ,M); DrawLINE(sx+1,sy+1,dx-1,sy+1,H); DrawLINE(sx+2,sy+2,dx-2,sy+2,L); DrawLINE(dx ,sy ,dx ,dy ,M); DrawLINE(dx-1,sy+1,dx-1,dy-1,H); DrawLINE(dx-2,sy+2,dx-2,dy-2,L); DrawLINE(sx ,sy ,sx ,dy ,L); DrawLINE(sx+1,sy+1,sx+1,dy-1,H); DrawLINE(sx+2,sy+2,sx+2,dy-2,M); DrawLINE(sx ,dy ,dx ,dy ,L); DrawLINE(sx+1,dy-1,dx-1,dy-1,H); DrawLINE(sx+2,dy-2,dx-2,dy-2,M); } // ************************************************************************************************ // 秀中文字 // ************************************************************************************************ void ShowChinese(LPRECT lpRect,char *String,DWORD StringLen,COLORREF GForeColor,COLORREF GBackColor) { SetTextColor(hDC,GForeColor); if(GBackColor==RGB(0,0,0)) SetBkMode(hDC,TRANSPARENT); else SetBkColor(hDC,GBackColor); StringLen=StringLen lpDD->CreateSurface(&ddsd,&BackupImage[BackNo],NULL); if(ddrval!=DD_OK) { D3DAppISetErrorString("CreateSurface for texture failed (loadtex).\n%s", D3DAppErrorToString(ddrval)); return NULL; } rcSrc.left =x; rcSrc.top =y; rcSrc.right =x+DEFULTWND_WIDTH; rcSrc.bottom=y+40; while(TRUE) { hr=BackupImage[BackNo]->BltFast(0,0,d3dapp->lpBackBuffer,&rcSrc,DDBLTFAST_NOCOLORKEY); if(hr==DD_OK) break; if(hr==DDERR_SURFACELOST) if(!RestoreSurfaces()) break; if(hr!=DDERR_WASSTILLDRAWING) break; } if(d3dapp&&!d3dapp->bFullscreen) BackupImage[!BackNo]=BackupImage[BackNo]; } if(szCompStr) { SIZE Size; RECT rcSrc; HRESULT ddrval; char szBuffer[512]; rcSrc.left =0; rcSrc.top =0; rcSrc.right =DEFULTWND_WIDTH; rcSrc.bottom=40; while(TRUE) { hr=d3dapp->lpBackBuffer->BltFast(x,y,BackupImage[BackNo],&rcSrc,DDBLTFAST_NOCOLORKEY); if(hr==DD_OK) break; if(hr==DDERR_SURFACELOST) if(!RestoreSurfaces()) break; if(hr!=DDERR_WASSTILLDRAWING) break; } ddrval =d3dapp->lpBackBuffer->GetDC(&hDC); SelectObject(hDC,g_MessagehFont3); DrawLINE(x,y,x+DEFULTWND_WIDTH-1,y+39,RGB(0,64,64)); DrawCubicBox(x,y,x+DEFULTWND_WIDTH-1,y+39,255,255,0); x+=2; y+=2; if(lpHalfFullMode) { strcpy(szBuffer,lpHalfFullMode); GetTextExtentPoint32(hDC,szBuffer,strlen(szBuffer),&Size); DrawCubicBox(x,y,x+Size.cx,y+17,255,255,255); rcSrc.left =x; rcSrc.top =y; ShowChinese(&rcSrc,szBuffer,-1,RGB(128,255,128),RGB(0,0,0)); x+=Size.cx; } if(lpIMEDescription) { strcpy(szBuffer,lpIMEDescription); GetTextExtentPoint32(hDC,szBuffer,strlen(szBuffer),&Size); DrawCubicBox(x,y,x+Size.cx,y+17,255,255,255); rcSrc.left =x; rcSrc.top =y; ShowChinese(&rcSrc,szBuffer,-1,RGB(128,255,128),RGB(0,0,0)); x+=Size.cx; } if(strlen(szCompStr)) { GetTextExtentPoint32(hDC,szCompStr,dwCursorPos,&Size); rcSrc.left =x; rcSrc.top =y; ShowChinese(&rcSrc,szCompStr,-1,RGB(128,255,128),RGB(0,0,0)); x+=Size.cx; } if(JongCursor) { DrawLINE(x,y+17,x+9,y+17,RGB(128,255,255)); } d3dapp->lpBackBuffer->ReleaseDC(hDC); } } else if(BackupImage[BackNo]) { RECT rcSrc; x=CPF.ptCurrentPos.x; y=CPF.ptCurrentPos.y; rcSrc.left =0; rcSrc.top =0; rcSrc.right =DEFULTWND_WIDTH; rcSrc.bottom=40; while(TRUE) { hr=d3dapp->lpBackBuffer->BltFast(x,y,BackupImage[BackNo],&rcSrc,DDBLTFAST_NOCOLORKEY); if(hr==DD_OK) break; if(hr==DDERR_SURFACELOST) if(!RestoreSurfaces()) break; if(hr!=DDERR_WASSTILLDRAWING) break; } BackupImage[BackNo]->Release(); BackupImage[BackNo]=NULL; if(d3dapp&&!d3dapp->bFullscreen) BackupImage[!BackNo]=BackupImage[BackNo]; } ThisCursorTick=timeGetTime(); if(ThisCursorTick>LastCursorTick+500) { JongCursor=!JongCursor; LastCursorTick=ThisCursorTick; } return 1; } // ************************************************************************************************ // 中文輸入法(畫選字選單部分) // ************************************************************************************************ LRESULT HandleCandPaint(void) { long x,y; SIZE Size; RECT rcSrc; DWORD i,j,len; LPSTR lpstr; LPDWORD lpdwOffset; HRESULT ddrval; BYTE Shift[2]={ 0xF1,0x20 }; BYTE Right[2]={ 0xE8,0x20 }; if(lpCandList) { x=CPF.ptCurrentPos.x+9; y=CPF.ptCurrentPos.y+20; rcSrc.left =x; rcSrc.top =y; rcSrc.right =DEFULTWND_WIDTH; rcSrc.bottom=40; ddrval =d3dapp->lpBackBuffer->GetDC(&hDC); SelectObject(hDC,g_MessagehFont3); if(IsCompositionFinish) { SelectObject(hDC,g_MessagehFont4); GetTextExtentPoint32(hDC,(char*)Shift,2,&Size); rcSrc.left =x; rcSrc.top =y; ShowChinese(&rcSrc,(char*)Shift,2,RGB(128,255,128),RGB(0,0,0)); x+=Size.cx; SelectObject(hDC,g_MessagehFont3); } if(lpCandList->dwCount) { lpdwOffset =&lpCandList->dwOffset[0]; lpdwOffset+= lpCandList->dwPageStart; for(i=lpCandList->dwPageStart,j=0;(i dwCount)&&(i dwPageStart+lpCandList->dwPageSize);i++,j++) { lpstr=(LPSTR)lpCandList+*lpdwOffset++; len=strlen(lpstr); GetTextExtentPoint32(hDC,&CandNumber[j*2],2,&Size); rcSrc.left =x; rcSrc.top =y; ShowChinese(&rcSrc,&CandNumber[j*2],2,RGB(128,255,128),RGB(0,0,0)); x+=Size.cx; GetTextExtentPoint32(hDC,lpstr,len,&Size); if(i!=lpCandList->dwSelection) { rcSrc.left =x; rcSrc.top =y; ShowChinese(&rcSrc,lpstr,len,RGB(128,255,128),RGB(0,0,0)); } else { rcSrc.left =x; rcSrc.top =y; ShowChinese(&rcSrc,lpstr,len,RGB(128,255,128),RGB(0,0,0)); } x+=9*(len+1); } if(i dwCount) { SelectObject(hDC,g_MessagehFont4); GetTextExtentPoint32(hDC,(char*)Right,2,&Size); rcSrc.left =x; rcSrc.top =y; ShowChinese(&rcSrc,(char*)Right,2,RGB(128,255,128),RGB(0,0,0)); x+=Size.cx; SelectObject(hDC,g_MessagehFont3); } } d3dapp->lpBackBuffer->ReleaseDC(hDC); } return 1; } // ****************************************************************************************** // 中文輸入法(變換輸入模式部分) // ****************************************************************************************** extern HIMC hIMC; static WORD LayoutNum[2]= { MAKELANGID(LANG_ENGLISH,SUBLANG_ENGLISH_US), MAKELANGID(LANG_CHINESE,SUBLANG_CHINESE_TRADITIONAL) }; void ChangeMode(char ToggleLang,char ToggleHalf) { DWORD dwConv; DWORD dwSent; ActivateKeyboardLayout((HKL)LayoutNum[ToggleLang],KLF_ACTIVATE); ImmGetConversionStatus(hIMC,&dwConv,&dwSent); if(ToggleHalf) dwConv&=~IME_CMODE_FULLSHAPE; else dwConv|= IME_CMODE_FULLSHAPE; ImmSetConversionStatus(hIMC,dwConv,dwSent); } #define DBCSCODE 3 #define KeyinCodeMask 31 union _Key { WORD i; char c[2]; } k; BOOL bNextCodeIsDBCS=FALSE; char KeyinCodeFlag[256]; WORD KeyinCodeBuffer[KeyinCodeMask+1]; char KeyinScanBuffer[KeyinCodeMask+1]; long KeyinCodeHead=0; long KeyinCodeTail=0; extern BOOL g_bGetInputMessage; void HandleKeyinDown(long nVirtKey,long lKeyData) { if(g_bGetInputMessage) { if(((KeyinCodeHead+1)&KeyinCodeMask)!=KeyinCodeTail && !(KeyinCodeFlag[(nVirtKey&0xFF)]&0x01)) { KeyinCodeFlag[(nVirtKey&0xFF)]=0x01; KeyinCodeBuffer[KeyinCodeHead]=(WORD)(nVirtKey&0xFF); KeyinScanBuffer[KeyinCodeHead]=0x01; KeyinCodeHead++; KeyinCodeHead&=KeyinCodeMask; } } } void HandleKeyinUp(long nVirtKey,long lKeyData) { if(g_bGetInputMessage) { if(((KeyinCodeHead+1)&KeyinCodeMask)!=KeyinCodeTail) { KeyinCodeFlag[(nVirtKey&0xFF)]=0x00; KeyinCodeBuffer[KeyinCodeHead]=(WORD)(nVirtKey&0xFF); KeyinScanBuffer[KeyinCodeHead]=0x02; KeyinCodeHead++; KeyinCodeHead&=KeyinCodeMask; } } } void FeedKeyinCode(long nVirtKey,long lKeyData) { if(g_bGetInputMessage) { if(nVirtKey>=' ') { if(((KeyinCodeHead+1)&KeyinCodeMask)!=KeyinCodeTail) { KeyinCodeBuffer[KeyinCodeHead]=(WORD)(nVirtKey&0xFF); KeyinScanBuffer[KeyinCodeHead]=0x03; KeyinCodeHead++; KeyinCodeHead&=KeyinCodeMask; } } else if(nVirtKey!=VK_BACK) { if(((KeyinCodeHead+1)&KeyinCodeMask)!=KeyinCodeTail) { KeyinCodeBuffer[KeyinCodeHead]=(WORD)(nVirtKey&0xFF); KeyinScanBuffer[KeyinCodeHead]=0x01; KeyinCodeHead++; KeyinCodeHead&=KeyinCodeMask; } } } } char ReadKeyin(WORD *Keyin) { char Press; if(KeyinCodeTail==KeyinCodeHead) return 0; *Keyin=KeyinCodeBuffer[KeyinCodeTail]; Press=KeyinScanBuffer[KeyinCodeTail]; KeyinCodeTail++; KeyinCodeTail&=KeyinCodeMask; return Press; } RECT rcSrc; BOOL JongCursor,InsertFlag,InputRedraw[2]={ FALSE,FALSE }; char *phrase=NULL; long xorg,slen; long xloc,yloc; long xpos,ypos,wval,hval; DWORD LastKeyingTick; DWORD LastCursorTick; // LPDIRECTDRAWSURFACE InputArea=NULL; extern rmfullglobals myglobs; extern CMenuCreateNew m_MenuCreateNew; void CheckBufferPhrase(char *buffer,char *phrase) { DWORD i; for(i=0;i (xloc-xorg)+1;i--) { phrase[i]=phrase[i-2]; buffer[i]=buffer[i-2]; } phrase[xloc ]=2; // 中文一 phrase[xloc+1]=3; // 中文二 buffer[xloc++]=k.c[0]; ReadKeyin(&k.i); buffer[xloc++]=k.c[0]; InputRedraw[0]=TRUE; InputRedraw[1]=TRUE; } // 字數檢查 else if(xloc-xorg (xloc-xorg);i--) { phrase[i]=phrase[i-1]; buffer[i]=buffer[i-1]; } phrase[xloc ]=1; // 英文 buffer[xloc++]=k.c[0]; InputRedraw[0]=TRUE; InputRedraw[1]=TRUE; } // 字數檢查 else if(xloc-xorg LastKeyingTick+500) { k.i=KeyCode; } if(k.i) { switch(k.c[0]) { case VK_BACK: // BACKSPACE if((xloc-xorg>0&&phrase[xloc-xorg-1]==3)||(xloc-xorg>1&&phrase[xloc-xorg-2]==2)) loops=2; else loops=1; for(j=0;j 0) { xloc--; for(i=(xloc-xorg);i 0;i--) { if(i<0) break; if(phrase[i]==1&&buffer[i]!=0x20) break; if(phrase[i]==3&&buffer[i--]!=0x40&&buffer[i]!=0xA1) break; } xloc=xorg+i+1; InputRedraw[0]=TRUE; InputRedraw[1]=TRUE; break; case VK_INSERT: //INS InsertFlag=!InsertFlag; break; case VK_DELETE: //DEL if(xloc-xorg =loops) { for(j=0;j 0) { xloc--; } } InputRedraw[0]=TRUE; InputRedraw[1]=TRUE; } break; case VK_RIGHT: //RIGHT if(phrase[xloc-xorg]==2) loops=2; else loops=1; if(xloc-xorg lpBackBuffer->GetDC(&hDC); SelectObject(hDC,g_MessagehFont3); rcSrc.left =xpos; rcSrc.top =ypos; // PutIMG(xpos-2,ypos-2,InputArea); // if(m_MenuCreateNew.bPassword) // ShowChinese(&rcSrc,altime,strlen(Rtrim(buffer)),RGB(255,255,255),RGB(0,0,0)); // else ShowChinese(&rcSrc,buffer,strlen(Rtrim(buffer)),RGB(255,255,255),RGB(0,0,0)); if(JongCursor) { GetTextExtentPoint32(hDC,buffer,xloc,&Size); if(InsertFlag) DrawLINE(xpos+Size.cx,ypos ,xpos+Size.cx+9,ypos+17,RGB(255,255,255)); else DrawLINE(xpos+Size.cx,ypos+17,xpos+Size.cx+9,ypos+17,RGB(255,255,255)); } d3dapp->lpBackBuffer->ReleaseDC(hDC); } ThisCursorTick=timeGetTime(); if(ThisCursorTick>LastCursorTick+500) { JongCursor=!JongCursor; LastCursorTick=ThisCursorTick; InputRedraw[0]=TRUE; InputRedraw[1]=TRUE; } HandleCompPaint(); HandleCandPaint(); return Retval; } void InputFinish(void) { ChangeMode(0,TRUE); HandleCompPaint(); HandleCandPaint(); DisableIME(myglobs.hWndMain); // if(InputArea) { Free(InputArea); InputArea=NULL; } if(phrase) { free(phrase); phrase=NULL; } } extern DEVMODE g_DevMode; BOOL InitResolution(void) { long iSel=-1; DWORD iMode=0; DEVMODE DevMode; //設定顯示模式 g_DevMode.dmSize=sizeof(DEVMODE); EnumDisplaySettings(NULL,ENUM_CURRENT_SETTINGS,&g_DevMode); iSel=-1; // 先找解析度和目前一樣的 iMode=0; while(TRUE) { DevMode.dmSize=sizeof(DEVMODE); if(!EnumDisplaySettings(NULL,iMode,&DevMode)) break; if(DevMode.dmBitsPerPel==16&&DevMode.dmPelsWidth==g_DevMode.dmPelsWidth&&DevMode.dmPelsHeight==g_DevMode.dmPelsHeight) { iSel=iMode; DevMode.dmFields=DM_BITSPERPEL; DevMode.dmBitsPerPel=16; ChangeDisplaySettingsEx(NULL,&DevMode,NULL,CDS_UPDATEREGISTRY,NULL); } iMode++; } // 找到沒 if(iSel<0) { // 再找解析度比預設高的即可但可與目前不同 iMode=0; while(TRUE) { DevMode.dmSize=sizeof(DEVMODE); if(!EnumDisplaySettings(NULL,iMode,&DevMode)) break; if(DevMode.dmBitsPerPel==16&&DevMode.dmPelsWidth>=DEFULTWND_WIDTH&&DevMode.dmPelsHeight>=DEFULTWND_HEIGHT) { iSel=iMode; DevMode.dmFields=DM_BITSPERPEL|DM_PELSWIDTH|DM_PELSHEIGHT; DevMode.dmBitsPerPel=16; ChangeDisplaySettingsEx(NULL,&DevMode,NULL,CDS_UPDATEREGISTRY,NULL); break; } iMode++; } if(iSel<0) { return FALSE; } } return TRUE; } void QuitResolution(void) { g_DevMode.dmSize=sizeof(DEVMODE); g_DevMode.dmFields=DM_BITSPERPEL|DM_PELSWIDTH|DM_PELSHEIGHT; ChangeDisplaySettingsEx(NULL,&g_DevMode,NULL,CDS_UPDATEREGISTRY,NULL); } void ProcessMessage(void) { MSG Msg; if(PeekMessage(&Msg,NULL,0,0,PM_REMOVE)) { if(Msg.message==WM_QUIT) { exit(1); } TranslateMessage(&Msg); DispatchMessage(&Msg); } }