static BOOL _queryMouseMove(PGROPDATA pGrop, LONG lX, LONG lY) { POINTL pointl; ULONG ulVAWidth = pGrop->rectlViewArea.xRight - pGrop->rectlViewArea.xLeft; ULONG ulVAHeight = pGrop->rectlViewArea.yTop - pGrop->rectlViewArea.yBottom; // For compatibility with some SDL-programs simulating the relative mouse // motion (for ex. OpenTyrian). pGrop->fCapture = FALSE; // Restrict the movement of the mouse user work area. if ( lX < 0 ) lX = 0; else if ( lX >= pGrop->stUserMode.ulWidth ) lX = pGrop->stUserMode.ulWidth - 1; if ( lY < 0 ) lY = 0; else if ( lY >= pGrop->stUserMode.ulHeight ) lY = pGrop->stUserMode.ulHeight - 1; // Scale coordinates from work area to the view area. pointl.x = pGrop->rectlViewArea.xLeft + ( ( ulVAWidth * lX ) / pGrop->stUserMode.ulWidth ); pointl.y = pGrop->rectlViewArea.yBottom + ( ulVAHeight * lY ) / pGrop->stUserMode.ulHeight; WinMapWindowPoints( pGrop->hwnd, pGrop->hwndDT, &pointl, 1 ); pGrop->lSkipMouseMove++; return WinSetPointerPos( pGrop->hwndDT, pointl.x, pointl.y ); }
void Window::remapCoordinates( Window *from, Window *to, int &x, int &y ) { POINTL ptl = {x,y}; WinMapWindowPoints( from->getHWND(), to->getHWND(), &ptl, 1 ); x = ptl.x; y = ptl.y; }
void Window::getCursorPos( int &x, int &y ) { POINTL ptl; WinQueryPointerPos( HWND_DESKTOP, &ptl ); WinMapWindowPoints( HWND_DESKTOP, hWndClient, &ptl, 1 ); x = ptl.x; y = ptl.y; }
void OS2Popup::show( int xPos, int yPos ) { POINTL ptl = { xPos, yPos }; // Invert Y ptl.y = ( WinQuerySysValue( HWND_DESKTOP, SV_CYSCREEN ) - 1 ) - ptl.y; WinMapWindowPoints( HWND_DESKTOP, m_hWnd, &ptl, 1 ); WinPopupMenu( m_hWnd, m_hWnd, m_hMenu, ptl.x, ptl.y, 0, PU_HCONSTRAIN | PU_VCONSTRAIN | PU_NONE | PU_KEYBOARD | PU_MOUSEBUTTON1 | PU_MOUSEBUTTON2 ); }
void ShowObjMenu( HWND hwnd) { ULONG rc = 0; ULONG ulHndl; PRWSHDR pHdr = 0; PMINIRECORDCORE pRec; POINTL ptl; do { pRec = precMenu; precMenu = 0; // this should only be called if the single-object menu was used if (pRec == 0) ERRNBR( 1) // get the object's handle from the Key column ulHndl = strtoul( ((char**)&pRec[1])[eKEY], 0, 10); // get the mouse position & convert to container coordinates WinQueryPointerPos( HWND_DESKTOP, &ptl); WinMapWindowPoints( HWND_DESKTOP, hCnr, &ptl, 1); // this command calls wpDisplayMenu() with the "important" arguments // preset by RwsServer; hwnd is the window that should get the focus // when the menu is dismissed, and ptl is the menu location in hwnd // coordinates - both arguments are optional; the command returns // the popupmenu's hwnd which we don't use here ERRRTN( RwsCall( &pHdr, RWSP_CMD, RWSCMD_POPUPMENU, RWSR_ASIS, 0, 3, RWSI_OHNDL, 0, ulHndl, RWSI_ASIS, 0, hCnr, RWSI_PBUF, sizeof(POINTL), (ULONG)&ptl)) } while (fFalse); if (rc) { RwsGetRcString( rc, sizeof( szError), szError); printf( "ShowObjMenu: rc= %d %s\n", rc, szError); } // free the server request block RwsFreeMem( pHdr); return; }
void checkScrollbars(WINDOWINFO *pwi, POINTL ptl) { RECTL rcl; WinQueryWindowRect(view.hwndClient,&rcl); GpiConvert(pwi->hps,CVTC_DEFAULTPAGE,CVTC_DEVICE,1,&ptl); WinMapWindowPoints(pwi->hwndClient,view.hwndClient,&ptl,1); if (ptl.y < 0) WinSendMsg(view.hwndClient,WM_VSCROLL,(MPARAM)0, MPFROM2SHORT(0,SB_LINEDOWN)); if (ptl.x > rcl.xRight) WinSendMsg(view.hwndClient,WM_HSCROLL,(MPARAM)0, MPFROM2SHORT(0,SB_LINERIGHT)); }
static APIRET APIENTRY woSetup( PKVASETUP pkvas ) { m_hwvs.ulLength = sizeof( HWVIDEOSETUP ); m_hwvs.rctlSrcRect = pkvas->rclSrcRect; m_hwvs.szlSrcSize = pkvas->szlSrcSize; m_hwvs.fccColor = pkvas->fccSrcColor; m_hwvs.ulSrcPitch = ( m_hwvs.szlSrcSize.cx * 2 + m_hwvc.ulScanAlign ) & ~m_hwvc.ulScanAlign; kvaAdjustDstRect( &m_hwvs.rctlSrcRect, &m_hwvs.rctlDstRect ); WinMapWindowPoints( m_hwndKVA, HWND_DESKTOP, ( PPOINTL )&m_hwvs.rctlDstRect, 2 ); if( m_hwvs.rctlDstRect.xLeft == m_hwvs.rctlDstRect.xRight || m_hwvs.rctlDstRect.yTop == m_hwvs.rctlDstRect.yBottom ) return m_pfnHWVIDEOSetup( NULL ); return m_pfnHWVIDEOSetup( &m_hwvs ); }
static VOID _captureMouse(PGROPDATA pGrop, BOOL fCapture) { SWP swp; POINTL pointl; if ( fCapture ) { WinSetCapture( pGrop->hwndDT, pGrop->hwnd ); WinQueryWindowPos( pGrop->hwnd, &swp ); pointl.x = swp.cx / 2; pointl.y = swp.cy / 2; WinMapWindowPoints( pGrop->hwnd, pGrop->hwndDT, &pointl, 1 ); pGrop->lSkipMouseMove++; WinSetPointerPos( pGrop->hwndDT, pointl.x, pointl.y ); } else WinSetCapture( pGrop->hwndDT, NULLHANDLE ); }
static MRESULT EXPENTRY woNewWindowProc( HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2 ) { switch( msg ) { case WM_ERASEBACKGROUND : { HPS hpsFrame = ( HPS )mp1; PRECTL prcl = ( PRECTL )mp2; GpiCreateLogColorTable( hpsFrame, 0, LCOLF_RGB, 0, 0, NULL ); WinFillRect( hpsFrame, prcl, m_hwvs.ulKeyColor); return FALSE; } case WM_SIZE : case WM_MOVE : // WinMapWindowPoints() sometimes does a wrong conversion on WM_MOVE. // For examples, minimizing and restoring a window of Qt4. // So we need to setup on WM_PAINT as well in order to work around // this problem. case WM_PAINT : { RECTL rcl; kvaAdjustDstRect( &m_hwvs.rctlSrcRect, &rcl ); WinMapWindowPoints( hwnd, HWND_DESKTOP, ( PPOINTL )&rcl, 2 ); if( !WinEqualRect( WinQueryAnchorBlock( hwnd ), &rcl, &m_hwvs.rctlDstRect )) { m_hwvs.rctlDstRect = rcl; m_pfnHWVIDEOSetup( &m_hwvs ); } break; // fall through to old window proc } } return m_pfnwpOld( hwnd, msg, mp1, mp2 ); }
HBITMAP icqskin_createBackground(HWND hwnd, HBITMAP base) { SIZEL sizl = { 0, 0 }; DEVOPENSTRUC dop = {0L, "DISPLAY", NULL, 0L, 0L, 0L, 0L, 0L, 0L}; HAB hab = WinQueryAnchorBlock(hwnd); HBITMAP btm = NO_IMAGE; HWND owner = WinQueryWindow(hwnd, QW_OWNER); HPS hps; HDC hdc; SWP swp; BITMAPINFOHEADER2 bmih; BITMAPINFOHEADER bmpData; RECTL rcl; HBITMAP img; HBITMAP msk; HBITMAP bg; POINTL aptlPoints[4]; POINTL p; int f; int sz; WinQueryWindowPos(hwnd, &swp); hdc = DevOpenDC(hab, OD_MEMORY, "*", 5L, (PDEVOPENDATA)&dop, NULLHANDLE); hps = GpiCreatePS(hab, hdc, &sizl, PU_PELS | GPIT_MICRO | GPIA_ASSOC); /* Make base images */ GpiQueryBitmapParameters(base, &bmpData); memset(&bmih,0, sizeof(BITMAPINFOHEADER2)); bmih.cbFix = sizeof(bmih); bmih.cx = bmpData.cx; bmih.cy = bmpData.cy; bmih.cPlanes = 1; bmih.cBitCount = 1; msk = GpiCreateBitmap(hps, &bmih, 0L, NULL, NULL); GpiSetBitmap(hps,msk); aptlPoints[0].x=0; aptlPoints[0].y=0; aptlPoints[1].x=aptlPoints[0].x+bmpData.cx-1; aptlPoints[1].y=aptlPoints[0].y+bmpData.cy-1; aptlPoints[2].x=0; aptlPoints[2].y=0; aptlPoints[3].x=aptlPoints[2].x+bmpData.cx; aptlPoints[3].y=aptlPoints[2].y+bmpData.cy; GpiSetColor(hps,CLR_WHITE); GpiSetBackColor(hps,CLR_PINK); GpiWCBitBlt(hps,base,4,aptlPoints,ROP_NOTSRCCOPY,BBO_IGNORE); /* Create base image */ bmih.cbFix = sizeof(bmih); bmih.cx = bmpData.cx; bmih.cy = bmpData.cy; bmih.cPlanes = 1; bmih.cBitCount = 24; img = GpiCreateBitmap( hps, &bmih, 0L, NULL, NULL); GpiSetBitmap(hps,img); GpiSetColor(hps,CLR_WHITE); GpiSetBackColor(hps,CLR_BLACK); GpiWCBitBlt( hps,msk,4,aptlPoints,ROP_NOTSRCCOPY,BBO_IGNORE); GpiWCBitBlt( hps,base,4,aptlPoints,ROP_SRCAND,BBO_IGNORE); /* Draw background */ memset(&bmih,0, sizeof(BITMAPINFOHEADER2)); bmih.cbFix = sizeof(bmih); bmih.cx = swp.cx; bmih.cy = swp.cy; bmih.cPlanes = 1; bmih.cBitCount = 24; btm = GpiCreateBitmap(hps,&bmih,0L,NULL,NULL); GpiSetBitmap(hps, btm); // Ask owner window to draw the background icqskin_loadPallete(hps, 0, (const ULONG *) WinSendMsg(hwnd,WMICQ_QUERYPALLETE,0,0)); rcl.xLeft = rcl.yBottom = 0; rcl.xRight = swp.cx; rcl.yTop = swp.cy; bg = icqskin_queryBackground(owner); if(!bg || bg == NO_IMAGE) { WinFillRect(hps, &rcl, ICQCLR_BACKGROUND); } else { WinMapWindowPoints(hwnd, owner, (POINTL *) &rcl, 2); p.x = p.y = 0; WinDrawBitmap(hps, bg, &rcl, &p, CLR_WHITE, CLR_BLACK, DBM_NORMAL); } GpiSetColor(hps,CLR_WHITE); GpiSetBackColor(hps,CLR_BLACK); if(swp.cx > bmpData.cx) { sz = bmpData.cx / 3; for(f=sz;f<(swp.cx-(sz*2));f += sz) drawTransparent(hps, img, msk, f, 0, sz, bmpData.cy, sz, 0); drawTransparent(hps, img, msk, swp.cx-(sz*2), 0, sz, bmpData.cy, sz, 0); drawTransparent(hps, img, msk, 0, 0, sz, bmpData.cy, 0, 0); drawTransparent(hps, img, msk, swp.cx-sz, 0, sz, bmpData.cy, bmpData.cx-sz, 0); } else { sz = swp.cx / 2; drawTransparent(hps, img, msk, 0, 0, sz, bmpData.cy, 0, 0); drawTransparent(hps, img, msk, sz, 0, sz, bmpData.cy, bmpData.cx-sz, 0); } // Release resources GpiSetBitmap(hps, NULLHANDLE); GpiDeleteBitmap(img); GpiDeleteBitmap(msk); GpiDestroyPS(hps); DevCloseDC(hdc); return btm; }
MRESULT EXPENTRY ClientWndProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2) { static HWND hwndFrame, hwndButton[10]; static INT cxClient, cyClient, cyChar; static LONG ButtonWidth, ButtonHeight; static CLR buttonColour; CHAR szBuffer[32]; FONTMETRICS fm; HAB hab; HPS hps; INT id; RECTL rcl; switch(msg) { case WM_CREATE: hab = WinQueryAnchorBlock(hwnd); hwndFrame = WinQueryWindow(hwnd, QW_PARENT); hps = WinGetPS(hwnd); GpiQueryFontMetrics(hps, sizeof(fm),&fm); cyChar = fm.lMaxBaselineExt; WinReleasePS(hps); buttonColour.Index = 0x00CCCCCC; // Buttons should be big enough to hold the pointer, with a 4 pixel border ButtonWidth = WinQuerySysValue(HWND_DESKTOP, SV_CXPOINTER) + 4; ButtonHeight = WinQuerySysValue(HWND_DESKTOP, SV_CYPOINTER) + 4; hwndButton[0] = WinCreateWindow(hwnd, SHADEDBTNCLASS, "100", WS_VISIBLE | GBT_NORIGHTLINE | GBT_GRAPHIC, 0, 0, ButtonWidth, ButtonHeight, hwnd, HWND_BOTTOM, 0, NULL, NULL); hwndButton[1] = WinCreateWindow(hwnd, SHADEDBTNCLASS, "101", WS_VISIBLE | GBT_NOLEFTLINE | GBT_GRAPHIC, 0, 0, ButtonWidth, ButtonHeight, hwnd, HWND_BOTTOM, 1, NULL, NULL); // This is the status bar hwndButton[2] = WinCreateWindow(hwnd, SHADEDBTNCLASS, "Status Bar", WS_VISIBLE | GBT_NOPUSH, 0, 0, 0, cyChar * 5 / 4, hwnd, HWND_BOTTOM, 2, NULL, NULL); sprintf(szBuffer, "Red: %d Green: %d Blue: %d", buttonColour.rgb.red, buttonColour.rgb.green, buttonColour.rgb.blue); WinSetWindowText(hwndButton[2], szBuffer); // Buttons to change the colour of the about button hwndButton[3] = WinCreateWindow(hwnd, SHADEDBTNCLASS, "<", WS_VISIBLE | GBT_NORIGHTLINE, 0, 0, ButtonWidth, cyChar * 5 / 4, hwnd, HWND_BOTTOM, 3, NULL, NULL); hwndButton[4] = WinCreateWindow(hwnd, SHADEDBTNCLASS, ">", WS_VISIBLE | GBT_NOLEFTLINE, 0, 0, ButtonWidth, cyChar * 5 / 4, hwnd, HWND_BOTTOM, 4, NULL, NULL); hwndButton[5] = WinCreateWindow(hwnd, SHADEDBTNCLASS, "<", WS_VISIBLE | GBT_NORIGHTLINE, 0, 0, ButtonWidth, cyChar * 5 / 4, hwnd, HWND_BOTTOM, 5, NULL, NULL); hwndButton[6] = WinCreateWindow(hwnd, SHADEDBTNCLASS, ">", WS_VISIBLE | GBT_NOLEFTLINE, 0, 0, ButtonWidth, cyChar * 5 / 4, hwnd, HWND_BOTTOM, 6, NULL, NULL); hwndButton[7] = WinCreateWindow(hwnd, SHADEDBTNCLASS, "<", WS_VISIBLE | GBT_NORIGHTLINE, 0, 0, ButtonWidth, cyChar * 5 / 4, hwnd, HWND_BOTTOM, 7, NULL, NULL); hwndButton[8] = WinCreateWindow(hwnd, SHADEDBTNCLASS, ">", WS_VISIBLE | GBT_NOLEFTLINE, 0, 0, ButtonWidth, cyChar * 5 / 4, hwnd, HWND_BOTTOM, 8, NULL, NULL); // info about this program hwndButton[9] = WinCreateWindow(hwnd, SHADEDBTNCLASS, "About", WS_VISIBLE | GBT_RIGHTROUND | GBT_LEFTROUND, 0, 0, 2 * ButtonWidth, cyChar * 5 / 4, hwnd, HWND_BOTTOM, 9, NULL, NULL); // change the colour of the buttons WinSendMsg(hwndButton[3], GBM_SETCOLOR, MPFROMLONG(0x00FFCCCC), NULL); WinSendMsg(hwndButton[4], GBM_SETCOLOR, MPFROMLONG(0x00FFCCCC), NULL); WinSendMsg(hwndButton[5], GBM_SETCOLOR, MPFROMLONG(0x00CCFFCC), NULL); WinSendMsg(hwndButton[6], GBM_SETCOLOR, MPFROMLONG(0x00CCFFCC), NULL); WinSendMsg(hwndButton[7], GBM_SETCOLOR, MPFROMLONG(0x00CCCCFF), NULL); WinSendMsg(hwndButton[8], GBM_SETCOLOR, MPFROMLONG(0x00CCCCFF), NULL); WinSendMsg(hwndButton[9], GBM_SETCOLOR, MPFROMLONG(buttonColour.Index), NULL); return 0; case WM_SIZE: hps = WinGetPS(hwnd); GpiQueryFontMetrics(hps, sizeof(fm),&fm); cyChar = fm.lMaxBaselineExt; WinReleasePS(hps); cxClient = SHORT1FROMMP(mp2); cyClient = SHORT2FROMMP(mp2); // Center the buttons for(id = 0; id < 2; id++) WinSetWindowPos(hwndButton[id], NULLHANDLE, (cxClient >> 1) + ButtonWidth * (id - 1), (cyClient - ButtonHeight) >> 1, 0, 0, SWP_MOVE); for(id = 3; id < 9; id++) WinSetWindowPos(hwndButton[id], NULLHANDLE, (cxClient >> 1) + ButtonWidth * (-(id % 2)), ((cyClient + ButtonHeight) >> 1) + (3 - (id-1) / 2) * cyChar * 5 / 4, 0, 0, SWP_MOVE); WinSetWindowPos(hwndButton[9], NULLHANDLE, (cxClient >> 1) - ButtonWidth, ((cyClient - ButtonHeight) >> 1) - cyChar * 15 / 8, 0, 0, SWP_MOVE); // make the status bar span the width of the window WinSetWindowPos(hwndButton[2], NULLHANDLE, 0, 0, cxClient, cyChar * 5 / 4, SWP_SIZE); // Enable "Smaller" button if window is large enough for the buttons if (!WinIsWindowEnabled(hwndButton[0]) && ((9 * cxClient / 10) >= (2 * ButtonWidth)) && ((9 * cyClient / 10) >= (ButtonHeight + cyChar * 15 / 2))) WinEnableWindow(hwndButton[0], TRUE); // Disable "Smaller" button if window is too small for the buttons if (WinIsWindowEnabled(hwndButton[0]) && (((9 * cxClient / 10) < (2 * ButtonWidth)) || ((9 * cyClient / 10) < (ButtonHeight + cyChar * 15 / 2)))) WinEnableWindow(hwndButton[0], FALSE); return 0; case WM_COMMAND: WinQueryWindowRect(hwnd, &rcl); WinMapWindowPoints(hwnd, HWND_DESKTOP, (PPOINTL) &rcl, 2); switch(COMMANDMSG(&msg)->cmd) { case 0: // "Smaller" rcl.xLeft += cxClient / 20; rcl.xRight -= cxClient / 20; rcl.yBottom += cyClient / 20; rcl.yTop -= cyClient / 20; break; case 1: // "Larger" rcl.xLeft -= cxClient / 20; rcl.xRight += cxClient / 20; rcl.yBottom -= cyClient / 20; rcl.yTop += cyClient / 20; break; case 3: // change red buttonColour.rgb.red--; if (buttonColour.rgb.red == 0) WinEnableWindow(hwndButton[3], FALSE); if (!WinIsWindowEnabled(hwndButton[4])) WinEnableWindow(hwndButton[4], TRUE); break; case 4: buttonColour.rgb.red++; if (buttonColour.rgb.red == 255) WinEnableWindow(hwndButton[4], FALSE); if (!WinIsWindowEnabled(hwndButton[3])) WinEnableWindow(hwndButton[3], TRUE); break; case 5: // change green buttonColour.rgb.green--; if (buttonColour.rgb.green == 0) WinEnableWindow(hwndButton[5], FALSE); if (!WinIsWindowEnabled(hwndButton[6])) WinEnableWindow(hwndButton[6], TRUE); break; case 6: buttonColour.rgb.green++; if (buttonColour.rgb.green == 255) WinEnableWindow(hwndButton[6], FALSE); if (!WinIsWindowEnabled(hwndButton[5])) WinEnableWindow(hwndButton[5], TRUE); break; case 7:// change blue buttonColour.rgb.blue--; if (buttonColour.rgb.blue == 0) WinEnableWindow(hwndButton[7], FALSE); if (!WinIsWindowEnabled(hwndButton[8])) WinEnableWindow(hwndButton[8], TRUE); break; case 8: buttonColour.rgb.blue++; if (buttonColour.rgb.blue == 255) WinEnableWindow(hwndButton[8], FALSE); if (!WinIsWindowEnabled(hwndButton[7])) WinEnableWindow(hwndButton[7], TRUE); break; case 9: WinDlgBox(HWND_DESKTOP, hwnd, AboutDlgProc, NULLHANDLE, IDD_ABOUT, NULL); return 0; } sprintf(szBuffer, "Red: %d Green: %d Blue: %d", buttonColour.rgb.red, buttonColour.rgb.green, buttonColour.rgb.blue); WinSetWindowText(hwndButton[2], szBuffer); WinCalcFrameRect(hwndFrame, &rcl, FALSE); WinSetWindowPos(hwndFrame, NULLHANDLE, rcl.xLeft, rcl.yBottom, rcl.xRight - rcl.xLeft, rcl.yTop - rcl.yBottom, SWP_MOVE | SWP_SIZE); WinPostMsg(hwndButton[9], GBM_SETCOLOR, MPFROMLONG(buttonColour.Index), NULL); return 0; case WM_ERASEBACKGROUND: WinFillRect((HPS)LONGFROMMP(mp1), PVOIDFROMMP(mp2), CLR_PALEGRAY); return 0; } return WinDefWindowProc(hwnd, msg, mp1, mp2); }
static VOID _wmMouseMove(PGROPDATA pGrop, SHORT lX, SHORT lY) { POINTL pointl; if ( ( pGrop->hptrPointer == NULLHANDLE ) && ( pGrop->fCapture /*|| pGrop->fFullscreen*/ ) ) { // Unvisible pointer when mouse captured /*or fullscreen*/ - relative mouse // mode. Send relative mouse coordinates (offset) to the application. // Mouse pointer is unvisible. WinSetPointer( pGrop->hwndDT, NULLHANDLE ); // Internal information about pointer in relative coordinates mode. pGrop->fMouseInViewArea = TRUE; pGrop->ulMouseX = pGrop->stUserMode.ulWidth / 2; pGrop->ulMouseY = pGrop->stUserMode.ulHeight / 2; // Center of the window in window coordinates. pointl.x = ( pGrop->rectlWinArea.xRight - pGrop->rectlWinArea.xLeft ) / 2; pointl.y = ( pGrop->rectlWinArea.yTop - pGrop->rectlWinArea.yBottom ) / 2; // Call user's function with relative coordinates. if ( pGrop->stCallback.fnMouseMove != NULL ) pGrop->stCallback.fnMouseMove( pGrop, TRUE, lX - pointl.x, lY - pointl.y ); // Keep mouse at center of the window. // Center of the window in screen coordinates. pointl.x = ( pGrop->rectlWinArea.xRight + pGrop->rectlWinArea.xLeft ) / 2; pointl.y = ( pGrop->rectlWinArea.yTop + pGrop->rectlWinArea.yBottom ) / 2; // Do not handle mouse move message when we moves to center of the window. pGrop->lSkipMouseMove++; if ( !WinSetPointerPos( pGrop->hwndDT, pointl.x, pointl.y ) ) debug( "WinSetPointerPos() failed" ); return; } if ( pGrop->fFullscreen || ( pGrop->fCapture && pGrop->fActive ) ) { // Restrict the movement of the mouse view area. SHORT lXva = lX, lYva = lY; if ( lX < pGrop->rectlViewArea.xLeft ) lX = pGrop->rectlViewArea.xLeft; else if ( lX >= pGrop->rectlViewArea.xRight ) lX = pGrop->rectlViewArea.xRight - 1; if ( lY < pGrop->rectlViewArea.yBottom ) lY = pGrop->rectlViewArea.yBottom; else if ( lY >= pGrop->rectlViewArea.yTop ) lY = pGrop->rectlViewArea.yTop - 1; if ( lX != lXva || lY != lYva ) { pointl.x = lX; pointl.y = lY; WinMapWindowPoints( pGrop->hwnd, pGrop->hwndDT, &pointl, 1 ); pGrop->lSkipMouseMove++; WinSetPointerPos( pGrop->hwndDT, pointl.x, pointl.y ); } } // Set application pointer when mouse on the view area or system pointer // when it on "unused" space of window (around view area in our window). pointl.x = lX; pointl.y = lY; WinSetPointer( pGrop->hwndDT, WinPtInRect( pGrop->hab, &pGrop->rectlViewArea, &pointl ) ? pGrop->hptrPointer : WinQuerySysPointer( HWND_DESKTOP, SPTR_ARROW, FALSE ) ); pGrop->fMouseInViewArea = lX >= pGrop->rectlViewArea.xLeft && lX < pGrop->rectlViewArea.xRight && lY >= pGrop->rectlViewArea.yBottom && lY < pGrop->rectlViewArea.yTop; if ( pGrop->fMouseInViewArea ) { ULONG ulVAWidth = pGrop->rectlViewArea.xRight - pGrop->rectlViewArea.xLeft; ULONG ulVAHeight = pGrop->rectlViewArea.yTop - pGrop->rectlViewArea.yBottom; // Set coordinates relative to the bottom-left corner of the view area. lX -= pGrop->rectlViewArea.xLeft; lY -= pGrop->rectlViewArea.yBottom; // Scale coordinates to the user work area. lX = pGrop->stUserMode.ulWidth * lX / ulVAWidth; lY = pGrop->stUserMode.ulHeight * lY / ulVAHeight; if ( ( pGrop->ulMouseX != lX ) || ( pGrop->ulMouseY != lY ) ) { // Coordinates hava been changed. pGrop->ulMouseX = lX; pGrop->ulMouseY = lY; // Call user's function. if ( pGrop->stCallback.fnMouseMove != NULL ) pGrop->stCallback.fnMouseMove( pGrop, FALSE, lX, lY ); } } }
static MRESULT handleDragOver(HWND hwnd, MPARAM mp1, MPARAM mp2) { MRESULT mResult; ULONG ulNumberOfObjects; PDRAGINFO pDragInfo; HPS hps; RECTL rectl; SWP swp; mResult = MRFROM2SHORT( DOR_NODROPOP, DO_LINK); /* Get access to the dragInfo */ pDragInfo=(PDRAGINFO)mp1; DrgAccessDraginfo(pDragInfo); /* Get number of items */ ulNumberOfObjects = DrgQueryDragitemCount( pDragInfo); if(ulNumberOfObjects>1) { /* Free the draginfo */ DrgFreeDraginfo(pDragInfo); return MRFROM2SHORT( DOR_NODROPOP, DO_LINK); } switch(pDragInfo->usOperation) { case DO_DEFAULT: case DO_LINK: if(!bDrawn) { POINTL ptl; launchPad * lp; ptl.x=SHORT1FROMMP(mp2); ptl.y=SHORT2FROMMP(mp2); /* Pos in window coords */ WinMapWindowPoints(HWND_DESKTOP, hwnd, &ptl, 1); hps=DrgGetPS(hwnd); WinQueryWindowPos(hwnd,&swp); rectl.xLeft=swp.cx;//-swp.cy; lp=(launchPad*)WinQueryWindowULong(hwnd,QWL_USER); if(lp) { if(lp->lpQueryNumObjects()==0) { rectl.xLeft=0; } } rectl.yTop=swp.cy-1; rectl.yBottom=1; if(ptl.x<rectl.xLeft) { int numB; numB=(ptl.x-xButtonOffset)/(swp.cy+xButtonDelta); rectl.xLeft=((ptl.x-numB*swp.cy) > swp.cy/2 ? numB+1: numB); rectl.xLeft*=(swp.cy+xButtonDelta); rectl.xLeft-=(xButtonDelta)-xButtonOffset+xButtonDelta; rectl.xRight=rectl.xLeft+(xButtonDelta*2); } else { rectl.xRight=swp.cx-1; } rclDrawn=rectl; WinDrawBorder(hps,&rectl, 2, 2, 0, 0, DB_STANDARD|DB_PATINVERT); bDrawn=TRUE; DrgReleasePS(hps); } mResult = MRFROM2SHORT( DOR_DROP, DO_LINK); break; default: break; } /* Free the draginfo */ DrgFreeDraginfo(pDragInfo); return mResult; }
MRESULT EXPENTRY SwapProc (HWND hwnd,ULONG msg,MPARAM mp1,MPARAM mp2) { static HWND hwndMenu = (HWND)0; switch(msg) { case WM_CREATE: { MRESULT mr = PFNWPStatic(hwnd,msg,mp1,mp2); WinSendMsg(hwnd, UM_SETUP, MPVOID, MPVOID); return mr; } case WM_MOUSEMOVE: break; case WM_PRESPARAMCHANGED: { char *rootname = "SwapMon"; switch(WinQueryWindowUShort(hwnd,QWS_ID)) { case CLOCK_FRAME: rootname = "Clock"; break; case HARD_FRAME: rootname = "Hard"; break; case CPU_FRAME: rootname = "CPU"; break; case CLP_FRAME: rootname = "ClipMon"; break; case MEM_FRAME: rootname = "Mem"; break; case TSK_FRAME: rootname = "Task"; break; } PresParamChanged(hwnd, rootname, mp1, mp2); PostMsg(hwnd, UM_TIMER, MPVOID, MPVOID); PostMsg(hwnd, UM_REFRESH, MPVOID, MPFROMSHORT(TRUE)); } break; case WM_APPTERMINATENOTIFY: if(WinQueryWindowUShort(hwnd,QWS_ID) == CPU_FRAME) { if(!StartCPUThreads()) WinDestroyWindow(hwnd); } break; case WM_BUTTON1MOTIONSTART: { POINTL ptl; ptl.x = SHORT1FROMMP(mp1); ptl.y = SHORT2FROMMP(mp1); WinMapWindowPoints(hwnd, HWND_DESKTOP, &ptl, 1L); PostMsg(hwndConfig, UM_SHOWME, MPFROM2SHORT((USHORT)ptl.x,(USHORT)ptl.y), mp2); } return MRFROMSHORT(TRUE); case WM_BUTTON2MOTIONSTART: { TRACKINFO TrackInfo; SWP Position; memset(&TrackInfo,0,sizeof(TrackInfo)); TrackInfo.cxBorder = 1 ; TrackInfo.cyBorder = 1 ; TrackInfo.cxGrid = 1 ; TrackInfo.cyGrid = 1 ; TrackInfo.cxKeyboard = 8 ; TrackInfo.cyKeyboard = 8 ; WinQueryWindowPos(hwnd,&Position); TrackInfo.rclTrack.xLeft = Position.x ; TrackInfo.rclTrack.xRight = Position.x + Position.cx ; TrackInfo.rclTrack.yBottom = Position.y ; TrackInfo.rclTrack.yTop = Position.y + Position.cy ; WinQueryWindowPos(HWND_DESKTOP,&Position); TrackInfo.rclBoundary.xLeft = Position.x ; TrackInfo.rclBoundary.xRight = Position.x + Position.cx ; TrackInfo.rclBoundary.yBottom = Position.y ; TrackInfo.rclBoundary.yTop = Position.y + Position.cy ; TrackInfo.ptlMinTrackSize.x = 0 ; TrackInfo.ptlMinTrackSize.y = 0 ; TrackInfo.ptlMaxTrackSize.x = Position.cx ; TrackInfo.ptlMaxTrackSize.y = Position.cy ; TrackInfo.fs = TF_MOVE | TF_STANDARD | TF_ALLINBOUNDARY ; if(WinTrackRect(HWND_DESKTOP, (HPS)0, &TrackInfo)) { WinSetWindowPos(hwnd, HWND_TOP, TrackInfo.rclTrack.xLeft, TrackInfo.rclTrack.yBottom, 0, 0, SWP_MOVE); switch(WinQueryWindowUShort(hwnd,QWS_ID)) { case SWAP_FRAME: WinQueryWindowPos(hwnd,&swpSwap); SavePrf("SwapSwp", &swpSwap, sizeof(SWP)); break; case CLOCK_FRAME: WinQueryWindowPos(hwnd,&swpClock); SavePrf("ClockSwp", &swpClock, sizeof(SWP)); break; case HARD_FRAME: WinQueryWindowPos(hwnd,&swpHard); SavePrf("HardSwp", &swpHard, sizeof(SWP)); break; case CPU_FRAME: WinQueryWindowPos(hwnd,&swpCPU); SavePrf("CPUSwp", &swpCPU, sizeof(SWP)); break; case CLP_FRAME: WinQueryWindowPos(hwnd,&swpClip); SavePrf("ClipSwp", &swpClip, sizeof(SWP)); break; case MEM_FRAME: WinQueryWindowPos(hwnd,&swpMem); SavePrf("MemSwp", &swpMem, sizeof(SWP)); break; case TSK_FRAME: WinQueryWindowPos(hwnd,&swpTask); SavePrf("TaskSwp", &swpTask, sizeof(SWP)); break; } } } return MRFROMSHORT(TRUE); case WM_BUTTON1DOWN: WinSetWindowPos(hwnd, HWND_TOP, 0, 0, 0, 0, SWP_ZORDER | SWP_DEACTIVATE); return MRFROMSHORT(TRUE); case WM_BUTTON1DBLCLK: case WM_BUTTON1CLICK: if((!fNoMonClick && msg == WM_BUTTON1CLICK) || (fNoMonClick && msg == WM_BUTTON1DBLCLK)) { switch(WinQueryWindowUShort(hwnd,QWS_ID)) { case HARD_FRAME: { ULONG ulDriveNum,ulDriveMap,x; ulDriveMon = min(ulDriveMon,26); if(!DosQCurDisk(&ulDriveNum, &ulDriveMap)) { for(x = ulDriveMon + 1;x < 26;x++) { if(ulDriveMap & (1 << x)) { ulDriveMon = x; break; } } if(x >= 26) { for(x = 3;x < ulDriveMon - 1;x++) { if(ulDriveMap & (1 << x)) { ulDriveMon = x; break; } } } SavePrf("MonDrive", &ulDriveMon, sizeof(ULONG)); } PostMsg(hwnd, UM_TIMER, MPVOID, MPVOID); } break; case CLP_FRAME: case MEM_FRAME: case TSK_FRAME: case SWAP_FRAME: case CLOCK_FRAME: case CPU_FRAME: { USHORT cmd = CPU_PULSE; switch(WinQueryWindowUShort(hwnd,QWS_ID)) { case MEM_FRAME: cmd = CLOCK_CMDLINE; break; case TSK_FRAME: cmd = CPU_KILLPROC; break; case CLP_FRAME: cmd = CLOCK_CLIPBOARD; break; case SWAP_FRAME: cmd = SWAP_LAUNCHPAD; break; case CLOCK_FRAME: cmd = CLOCK_SETTINGS; if((WinGetKeyState(HWND_DESKTOP,VK_SHIFT) & 0x8000) != 0) cmd = CLOCK_CLOCK; break; } PostMsg(hwnd, WM_COMMAND, MPFROM2SHORT(cmd,0), MPVOID); } break; } return MRFROMSHORT(TRUE); } else PostMsg(hwnd, UM_TIMER, MPVOID, MPVOID); break; case WM_CONTEXTMENU: WinInvalidateRect(hwnd, NULL, FALSE); WinSendMsg(hwnd, UM_TIMER, MPVOID, MPVOID); WinSetWindowPos(hwnd, HWND_TOP, 0, 0, 0, 0, SWP_ZORDER | SWP_DEACTIVATE); { USHORT id; id = WinQueryWindowUShort(hwnd,QWS_ID); hwndMenu = WinLoadMenu(HWND_DESKTOP, 0, id); if(hwndMenu) { POINTL ptl; SWP swp; ULONG ulDriveNum,ulDriveMap,x; MENUITEM mi; char s[80]; SetPresParams(hwndMenu, -1, -1, -1, helvtext); switch(id) { case CLP_FRAME: WinSendMsg(hwndMenu, MM_SETITEMATTR, MPFROM2SHORT(CLP_APPEND,FALSE), MPFROM2SHORT(MIA_CHECKED, ((fClipAppend) ? MIA_CHECKED : 0))); break; case HARD_FRAME: if(!DosQCurDisk(&ulDriveNum, &ulDriveMap)) { mi.iPosition = 0; mi.hwndSubMenu = (HWND)0; mi.hItem = 0L; mi.afStyle = MIS_TEXT | MIS_STATIC; mi.afAttribute = MIA_FRAMED; mi.id = -1; sprintf(s, "Current drive is %c:", (char)(ulDriveMon + '@')); WinSendMsg(hwndMenu, MM_INSERTITEM, MPFROMP(&mi), MPFROMP(s)); mi.iPosition = MIT_END; for(x = 2;x < 26;x++) { if(ulDriveMap & (1 << x)) { if(x != ulDriveMon - 1) { mi.afStyle = MIS_TEXT; mi.afAttribute = 0; mi.id = HARD_C + (x - 2); if(fShowFreeInMenus) SetDriveText(x + 1, s); else sprintf(s, "%c:", (char)(x + 'A')); WinSendMsg(hwndMenu, MM_INSERTITEM, MPFROMP(&mi), MPFROMP(s)); } } } } break; case CLOCK_FRAME: WinEnableMenuItem(hwndMenu, CLOCK_VIRTUAL, fDesktops); WinEnableMenuItem(hwndMenu, CLOCK_CLIPBOARD, (ClipHwnd != (HWND)0)); break; default: break; } WinQueryWindowPos(hwnd, &swp); ptl.x = SHORT1FROMMP(mp1); ptl.y = SHORT2FROMMP(mp1); WinMapWindowPoints(hwnd, HWND_DESKTOP, &ptl, 1L); ptl.y = max(ptl.y,swp.y + swp.cy + 4); if(!WinPopupMenu(HWND_DESKTOP, hwnd, hwndMenu, ptl.x - 4, ptl.y - 4, 0, PU_HCONSTRAIN | PU_VCONSTRAIN | PU_KEYBOARD | PU_MOUSEBUTTON1)) { WinDestroyWindow(hwndMenu); hwndMenu = (HWND)0; } } } return MRFROMSHORT(TRUE); case WM_MENUEND: WinSetFocus(HWND_DESKTOP, HWND_DESKTOP); WinDestroyWindow((HWND)mp2); if(hwndMenu == (HWND)mp2) hwndMenu = (HWND)0; return 0; case UM_SETUP: { char *rootname = "SwapMon"; switch(WinQueryWindowUShort(hwnd,QWS_ID)) { case SWAP_FRAME: SwapHwnd = hwnd; swaptick = 0; break; case CLOCK_FRAME: ClockHwnd = hwnd; rootname = "Clock"; break; case TSK_FRAME: TaskHwnd = hwnd; rootname = "Task"; break; case MEM_FRAME: MemHwnd = hwnd; rootname = "Mem"; break; case HARD_FRAME: HardHwnd = hwnd; rootname = "Hard"; break; case CPU_FRAME: CPUHwnd = hwnd; rootname = "CPU"; PostMsg(hwnd, UM_REFRESH, MPVOID, MPFROMSHORT(TRUE)); break; case CLP_FRAME: ClipMonHwnd = hwnd; rootname = "ClipMon"; PostMsg(hwnd, UM_REFRESH, MPVOID, MPFROMSHORT(TRUE)); break; } if(!RestorePresParams(hwnd,rootname)) SetPresParams(hwnd, RGB_WHITE, RGB_BLACK, RGB_BLACK, helvtext); } PostMsg(hwnd, UM_TIMER, MPVOID, MPVOID); return 0; case UM_REFRESH: switch(WinQueryWindowUShort(hwnd,QWS_ID)) { case CLP_FRAME: { char s[] = " Clip: [TtBbMmP] + ",*p; ULONG fmt[] = {CF_TEXT,CF_DSPTEXT, CF_BITMAP,CF_DSPBITMAP, CF_METAFILE,CF_DSPMETAFILE, CF_PALETTE,0}; ULONG x,ret; if(WinOpenClipbrd(WinQueryAnchorBlock(hwnd))) { p = s + 8; for(x = 0;fmt[x];x++) { ret = WinQueryClipbrdData(WinQueryAnchorBlock(hwnd), fmt[x]); if(!ret) *p = '-'; p++; } p += 2; if(!fClipAppend) *p = 0; WinCloseClipbrd(WinQueryAnchorBlock(hwnd)); } else strcpy(s + 7, "Can't open. "); SetMonitorSize(hwnd, hwndMenu, &swpClip, s); } break; case CPU_FRAME: { char s[32]; ULONG percent,lastaverage; static BOOL lastavgset = 0; *s = 0; if(mp2) { strcpy(s," CPU: -% "); if(fAverage) strcat(s,"Avg: -%) "); } else { percent = ((MaxCount - (ULONG)mp1) * 100) / MaxCount; lastaverage = AveCPU; AveCPU = (((AveCPU * NumAveCPU) + percent) / ((ULONG)NumAveCPU + 1)); NumAveCPU++; if(!NumAveCPU) NumAveCPU = 65535; if(percent != LastPercent || (AveCPU != lastaverage && fAverage) || NumAveCPU == 1 || lastavgset != fAverage) { lastavgset = fAverage; LastPercent = percent; sprintf(s, " CPU: %lu%% ", percent); if(fAverage) sprintf(s + strlen(s), "(Avg: %lu%%) ", AveCPU); } } if(*s) SetMonitorSize(hwnd, hwndMenu, &swpCPU, s); } break; } return 0; case WM_TIMER: if(fSwapFloat && !hwndMenu) WinSetWindowPos(hwnd, HWND_TOP, 0, 0, 0, 0, SWP_ZORDER | SWP_SHOW); if(WinQueryWindowUShort(hwnd,QWS_ID) == CLP_FRAME) { if(!ClipHwnd) WinDestroyWindow(hwnd); else TakeClipboard(); } return 0; case UM_TIMER: switch(WinQueryWindowUShort(hwnd,QWS_ID)) { case CLP_FRAME: ClipMonHwnd = hwnd; WinSendMsg(hwnd, WM_TIMER, MPVOID, MPVOID); break; case CPU_FRAME: CPUHwnd = hwnd; WinSendMsg(hwnd, WM_TIMER, MPVOID, MPVOID); break; case HARD_FRAME: { char s[80]; HardHwnd = hwnd; SetDriveText(ulDriveMon, s); SetMonitorSize(hwnd, hwndMenu, &swpHard, s); } break; case SWAP_FRAME: { FILEFINDBUF3 ffb; ULONG nm = 1,fl = SWP_SIZE | SWP_SHOW | SWP_MOVE, sh,sl,nh; HDIR hdir = HDIR_CREATE; FSALLOCATE fsa; char s[128],ss[8],sss[8],mb,smb; static ULONG lastcbFile = 0; static BOOL warned = FALSE; static char SwapperDat[CCHMAXPATH] = ""; strcpy(s, " Unable to locate SWAPPER.DAT. "); SwapHwnd = hwnd; if(!*SwapperDat) FindSwapperDat(SwapperDat); if(*SwapperDat) { DosError(FERR_DISABLEHARDERR); if(!DosFindFirst(SwapperDat, &hdir, FILE_NORMAL | FILE_HIDDEN | FILE_SYSTEM | FILE_ARCHIVED | FILE_READONLY, &ffb, sizeof(ffb), &nm, FIL_STANDARD)) { DosFindClose(hdir); if(ffb.cbFile != lastcbFile && lastcbFile) swaptick = 9; lastcbFile = ffb.cbFile; DosError(FERR_DISABLEHARDERR); if(!DosQueryFSInfo(toupper(*SwapperDat) - '@', FSIL_ALLOC, &fsa, sizeof(FSALLOCATE))) nm = fsa.cUnitAvail * (fsa.cSectorUnit * fsa.cbSector); else nm = 0; if(nm <= 32768 * 1024) { swaptick = 10; if(!warned) { SetPresParams(hwnd, RGB_RED, -1, -1, NULL); warned = TRUE; DosBeep(250,15); } } else if(warned) { PostMsg(hwnd, UM_SETUP, MPVOID, MPVOID); warned = FALSE; } mb = MakeNumber(nm, &nh, &sl); *sss = 0; if(sl) sprintf(sss, ".%02lu", sl); smb = MakeNumber(ffb.cbFile, &sh, &sl); *ss = 0; if(sl) sprintf(ss, ".%02lu", sl); sprintf(s, " Swap: %lu%s%cb ", sh, ss, smb); if(fShowSwapFree) sprintf(s + strlen(s), "(%lu%s%cb free) ", nh, sss, mb); } } SetMonitorSize(hwnd, hwndMenu, &swpSwap, s); } break; case TSK_FRAME: { PROCESSINFO *ppi; BUFFHEADER *pbh = NULL; MODINFO *pmi; long numprocs = -1,numthreads = -1; char s[80]; if(!DosAllocMem((PVOID)&pbh, USHRT_MAX + 4096, PAG_COMMIT | OBJ_TILE | PAG_READ | PAG_WRITE)) { if(!DosQProcStatus(pbh, USHRT_MAX)) { numprocs = numthreads = 0; ppi = pbh->ppi; while(ppi->ulEndIndicator != PROCESS_END_INDICATOR ) { pmi = pbh->pmi; while(pmi && ppi->hModRef != pmi->hMod) pmi = pmi->pNext; if(pmi) { numprocs++; numthreads += ppi->usThreadCount; } ppi = (PPROCESSINFO)(ppi->ptiFirst + ppi->usThreadCount); } } DosFreeMem(pbh); sprintf(s, " Procs: %ld Thrds: %ld ", numprocs, numthreads); SetMonitorSize(hwnd, hwndMenu, &swpTask, s); } } break; case MEM_FRAME: { ULONG sh,sl,nh,amem; char s[128],ss[8],sss[8],mb,smb; strcpy(s, "Can't check virtual memory."); MemHwnd = hwnd; if(!DosQuerySysInfo(QSV_TOTAVAILMEM, QSV_TOTAVAILMEM, &amem, sizeof(amem))) { mb = MakeNumber(amem, &nh, &sl); *ss = 0; if(sl) sprintf(ss, ".%02lu", sl); sprintf(s, " VMem: %lu%s%cb ", nh, ss, mb); } if(fShowPMem) { if(!Dos16MemAvail(&amem)) { mb = MakeNumber(amem, &nh, &sl); *ss = 0; if(sl) sprintf(ss, ".%02lu", sl); sprintf(s + strlen(s), " PMem: %lu%s%cb ", nh, ss, mb); } } SetMonitorSize(hwnd, hwndMenu, &swpMem, s); } break; case CLOCK_FRAME: { char s[80]; DATETIME dt; ClockHwnd = hwnd; if(!DosGetDateTime(&dt)) { sprintf(s, " %0*u:%02u%s ", ((ampm) ? 0 : 2), (dt.hours % ((ampm) ? 12 : 24)) + ((ampm && !(dt.hours % 12)) ? 12 : 0), dt.minutes, ((ampm) ? (dt.hours > 11) ? "pm" : "am" : "")); if(showdate) sprintf(s + strlen(s), "%02u/%02u ", dt.month, dt.day); } else strcpy(s,"Unknown time"); SetMonitorSize(hwnd, hwndMenu, &swpClock, s); } break; } return 0; case WM_COMMAND: { BOOL ctrl,shift; ctrl = ((WinGetKeyState(HWND_DESKTOP,VK_CTRL) & 0x8000) != 0); shift = ((WinGetKeyState(HWND_DESKTOP,VK_SHIFT) & 0x8000) != 0); switch(SHORT1FROMMP(mp1)) { case CLP_CLEAR: if(WinOpenClipbrd(WinQueryAnchorBlock(hwnd))) { WinEmptyClipbrd(WinQueryAnchorBlock(hwnd)); WinCloseClipbrd(WinQueryAnchorBlock(hwnd)); PostMsg(hwnd, UM_REFRESH, MPVOID, MPVOID); } break; case CLP_APPEND: fClipAppend = (fClipAppend) ? FALSE : TRUE; SavePrf("ClipAppend", &fClipAppend, sizeof(BOOL)); PostMsg(hwnd, UM_REFRESH, MPVOID, MPVOID); if(ClipSetHwnd) PostMsg(ClipSetHwnd, UM_REFRESH, MPVOID, MPVOID); break; case MSE_HELP: ViewHelp(hwnd, "Monitors page"); break; case CPU_PULSE: { PROGDETAILS pgd; WinSetWindowPos(hwnd, HWND_TOP, 0, 0, 0, 0, SWP_ACTIVATE | SWP_FOCUSACTIVATE); memset(&pgd, 0, sizeof(pgd)); pgd.Length = sizeof(pgd); pgd.swpInitial.fl = SWP_ACTIVATE | SWP_ZORDER; pgd.swpInitial.hwndInsertBehind = HWND_TOP; pgd.progt.fbVisible = SHE_VISIBLE; pgd.progt.progc = PROG_DEFAULT; pgd.pszExecutable = "PULSE.EXE"; if(WinStartApp(CPUHwnd, &pgd, NULL, NULL, 0)) { if(CPUHwnd) { closethreads = 1; DosSleep(1); PostMsg(CPUHwnd, UM_REFRESH, MPVOID, MPFROMSHORT(TRUE)); } } } break; case CPU_RESET: AveCPU = 0; NumAveCPU = 0; break; case CLOCK_VIRTUAL: case CLOCK_SWITCHLIST: case CLOCK_CMDLINE: case CLOCK_CLIPBOARD: case CLOCK_CALCULATOR: case HARD_FM2: case MSE_FRAME: { ULONG msg2 = UM_SHOWME; MPARAM mp12 = 0,mp22 = 0; HWND hwndP = hwndConfig; switch(SHORT1FROMMP(mp1)) { case CLOCK_CMDLINE: mp12 = MPFROMLONG(((WinGetKeyState(HWND_DESKTOP,VK_CTRL) & 0x8000) != 0)); msg2 = UM_CMDLINE; break; case CLOCK_CLIPBOARD: msg2 = UM_CLIPMGR; hwndP = ObjectHwnd3; break; case CLOCK_SWITCHLIST: msg2 = UM_SWITCHLIST; break; case CLOCK_VIRTUAL: msg2 = UM_VIRTUAL; break; case CLOCK_CALCULATOR: msg2 = UM_CALC; break; case HARD_FM2: msg2 = UM_STARTWIN; mp12 = MPFROM2SHORT(C_STARTFM2,0); break; } PostMsg(hwndP, msg2, mp12, mp22); } break; case CLOCK_SETTINGS: case CLOCK_CLOCK: case SWAP_LAUNCHPAD: case SWAP_WARPCENTER: case SWAP_CONNECTIONS: case SWAP_INFO: case SWAP_SETTINGS: case SWAP_SYSTEM: case SWAP_TEMPS: case SWAP_FM2: case HARD_OPEN: case CVR_COLORPALETTE: case CVR_HICOLORPALETTE: case CVR_FONTPALETTE: case CPU_KILLPROC: case CPU_HARDWARE: { char *p = "<WP_CLOCK>",*pp = defopen; char s[8]; switch(SHORT1FROMMP(mp1)) { case HARD_OPEN: sprintf(s, "%c:\\", (char)(ulDriveMon + '@')); p = s; break; case SWAP_FM2: p = "<FM3_Folder>"; break; case SWAP_TEMPS: p = "<WP_TEMPS>"; break; case SWAP_SYSTEM: p = "<WP_OS2SYS>"; break; case SWAP_SETTINGS: p = "<WP_CONFIG>"; break; case SWAP_INFO: p = "<WP_INFO>"; break; case SWAP_CONNECTIONS: p = "<WP_CONNECTIONSFOLDER>"; break; case SWAP_WARPCENTER: p = "<WP_WARPCENTER>"; break; case SWAP_LAUNCHPAD: p = "<WP_LAUNCHPAD>"; break; case CLOCK_SETTINGS: pp = setopen; break; case CVR_COLORPALETTE: p = "<WP_LORESCLRPAL>"; break; case CVR_HICOLORPALETTE: p = "<WP_HIRESCLRPAL>"; break; case CVR_FONTPALETTE: p = "<WP_FNTPAL>"; break; case CPU_KILLPROC: p = "<FM/2_KILLPROC>"; break; case CPU_HARDWARE: p = "<WP_HWMGR>"; break; } OpenObject(p, pp); } break; case HARD_VDIR: { PROGDETAILS pgd; char s[36]; sprintf(s, "/C VDIR.CMD %c:\\", (char)(ulDriveMon + '@')); memset(&pgd, 0, sizeof(pgd)); pgd.Length = sizeof(pgd); pgd.swpInitial.fl = SWP_MINIMIZE | SWP_ACTIVATE | SWP_ZORDER; pgd.swpInitial.hwndInsertBehind = HWND_TOP; pgd.progt.fbVisible = SHE_VISIBLE; pgd.progt.progc = PROG_DEFAULT; pgd.pszExecutable = "CMD.EXE"; WinStartApp((HWND)0, &pgd, s, NULL, 0); } break; case HARD_CHKDSK: { PROGDETAILS pgd; char s[8]; WinSetWindowPos(hwnd, HWND_TOP, 0, 0, 0, 0, SWP_ACTIVATE | SWP_FOCUSACTIVATE); sprintf(s, "%c:", (char)(ulDriveMon + '@')); memset(&pgd, 0, sizeof(pgd)); pgd.Length = sizeof(pgd); pgd.swpInitial.fl = SWP_ACTIVATE | SWP_ZORDER; pgd.swpInitial.hwndInsertBehind = HWND_TOP; pgd.progt.fbVisible = SHE_VISIBLE; pgd.progt.progc = PROG_DEFAULT; pgd.pszExecutable = "PMCHKDSK.EXE"; WinStartApp((HWND)0, &pgd, s, NULL, 0); } break; default: if(SHORT1FROMMP(mp1) >= HARD_C && SHORT1FROMMP(mp1) <= HARD_C + 24) { ulDriveMon = (SHORT1FROMMP(mp1) - HARD_C) + 3; PostMsg(hwnd, UM_TIMER, MPVOID, MPVOID); if(ctrl) PostMsg(hwnd, WM_COMMAND, MPFROM2SHORT(HARD_OPEN,0), MPVOID); else if(shift) PostMsg(hwnd, WM_COMMAND, MPFROM2SHORT(HARD_VDIR,0), MPVOID); } break; } } return 0; case WM_DESTROY: switch(WinQueryWindowUShort(hwnd,QWS_ID)) { case SWAP_FRAME: SwapHwnd = (HWND)0; break; case CLOCK_FRAME: ClockHwnd = (HWND)0; break; case HARD_FRAME: HardHwnd = (HWND)0; break; case CPU_FRAME: closethreads = 1; DosSleep(1); CPUHwnd = (HWND)0; break; case CLP_FRAME: ClipMonHwnd = (HWND)0; break; case MEM_FRAME: MemHwnd = (HWND)0; break; case TSK_FRAME: TaskHwnd = (HWND)0; break; } break; } return PFNWPStatic(hwnd,msg,mp1,mp2); }
MRESULT EXPENTRY ClientWndProc (HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2) { static CHAR *szButtonLabel[] = { "Smaller", "Larger" } ; static HWND hwndFrame, hwndButton[2] ; static INT cxClient, cyClient, cxChar, cyChar ; FONTMETRICS fm ; HPS hps ; INT id ; RECTL rcl ; switch (msg) { case WM_CREATE : hwndFrame = WinQueryWindow (hwnd, QW_PARENT) ; hps = WinGetPS (hwnd) ; GpiQueryFontMetrics (hps, sizeof fm, &fm) ; cxChar = fm.lAveCharWidth ; cyChar = fm.lMaxBaselineExt ; WinReleasePS (hps) ; for (id = 0 ; id < 2 ; id++) hwndButton[id] = WinCreateWindow ( hwnd, // Parent WC_BUTTON, // Class szButtonLabel[id], // Text WS_VISIBLE | // Style BS_PUSHBUTTON, 0, 0, // Position 12 * cxChar, // Width 2 * cyChar, // Height hwnd, // Owner HWND_BOTTOM, // Placement id, // ID NULL, // Ctrl Data NULL) ; // Pres Params return 0 ; case WM_SIZE : cxClient = SHORT1FROMMP (mp2) ; cyClient = SHORT2FROMMP (mp2) ; for (id = 0 ; id < 2 ; id++) WinSetWindowPos (hwndButton[id], NULLHANDLE, cxClient / 2 + (14 * id - 13) * cxChar, (cyClient - 2 * cyChar) / 2, 0, 0, SWP_MOVE) ; return 0 ; case WM_COMMAND: WinQueryWindowRect (hwnd, &rcl) ; WinMapWindowPoints (hwnd, HWND_DESKTOP, (PPOINTL) &rcl, 2) ; switch (COMMANDMSG(&msg)->cmd) // Child ID { case 0: // "Smaller" rcl.xLeft += cxClient / 20 ; rcl.xRight -= cxClient / 20 ; rcl.yBottom += cyClient / 20 ; rcl.yTop -= cyClient / 20 ; break ; case 1: // "Larger" rcl.xLeft -= cxClient / 20 ; rcl.xRight += cxClient / 20 ; rcl.yBottom -= cyClient / 20 ; rcl.yTop += cyClient / 20 ; break ; } WinCalcFrameRect (hwndFrame, &rcl, FALSE) ; WinSetWindowPos (hwndFrame, NULLHANDLE, rcl.xLeft, rcl.yBottom, rcl.xRight - rcl.xLeft, rcl.yTop - rcl.yBottom, SWP_MOVE | SWP_SIZE) ; return 0 ; case WM_ERASEBACKGROUND: return MRFROMSHORT (1) ; } return WinDefWindowProc (hwnd, msg, mp1, mp2) ; }
/**************************************************************************** Main Message Cue Dialog Procedure *****************************************************************************/ MRESULT EXPENTRY MainDlgProc (HWND hWnd, ULONG msg, MPARAM mp1, MPARAM mp2) { BOOL Handled = TRUE; MRESULT mReturn = 0; ULONG ulScrWidth, ulScrHeight; RECTL Rectl; POINTL Pointl; HINI hini; ULONG temp; switch (msg) { /* Called on startup */ case WM_INITDLG: ulScrWidth = WinQuerySysValue (HWND_DESKTOP, SV_CXSCREEN); ulScrHeight = WinQuerySysValue (HWND_DESKTOP, SV_CYSCREEN); UPDATE_HOURS = TRUE; UPDATE_DATE = TRUE; DTSWITCH = FALSE; hini = HINI_USERPROFILE; Pointl.x = Pointl.y = 10; if(PrfQueryProfileSize(hini,pAppname,pKeyname,(PULONG)&temp) &&temp) { if(temp == sizeof(POINTL)) PrfQueryProfileData(hini, pAppname, pKeyname, &Pointl, (PULONG)&temp); } WinQueryWindowRect (hWnd, &Rectl); /* WinSetWindowPos (hWnd, HWND_TOP, Pointl.x, Pointl.y, 0, 0, SWP_SHOW | SWP_MOVE | SWP_ACTIVATE); */ WinSetWindowPos (hWnd, HWND_TOP, (ulScrWidth-Rectl.xRight)/2, (ulScrHeight-Rectl.yTop) - 10, 0, 0, SWP_SHOW | SWP_MOVE | SWP_ACTIVATE); /* A neat little trick to float the window on top... */ WinFocusChange(HWND_DESKTOP,HWND_TOP,0); timerID = WinStartTimer(hab, hWnd, 1, 1000L); break; case WM_TIMER: if(SHORT1FROMMP(mp1) == timerID) { while(DosGetDateTime( &(datetime[DTSWITCH?1:0]) )); UPDATE_HOURS = ( (datetime[DTSWITCH?1:0].minutes != datetime[DTSWITCH?0:1].minutes) || (datetime[DTSWITCH?1:0].hours != datetime[DTSWITCH?0:1].hours ) ); UPDATE_DATE |= ( (datetime[DTSWITCH?1:0].day != datetime[DTSWITCH?0:1].day ) || (datetime[DTSWITCH?1:0].weekday != datetime[DTSWITCH?0:1].weekday) || (datetime[DTSWITCH?1:0].month != datetime[DTSWITCH?0:1].month ) || (datetime[DTSWITCH?1:0].year != datetime[DTSWITCH?0:1].year ) ); ClockSetDateString( &(datetime[DTSWITCH?1:0])); DTSWITCH = !DTSWITCH; if(UPDATE_HOURS) { WinSetDlgItemText (hWnd, IDD_TIME, szHours); if(UPDATE_DATE) { WinSetWindowText(hWndFrame,(PSZ)szTitle); UPDATE_DATE = FALSE; } UPDATE_HOURS = FALSE; } WinSetDlgItemText (hWnd, IDD_SEC, szSecs); } Handled = FALSE; break; case WM_SYSCOMMAND: case WM_COMMAND: switch (LOUSHORT(mp1)) { case SC_CLOSE: hini = HINI_USERPROFILE; WinStopTimer(hab, hWnd, timerID); Pointl.x = Pointl.y = 0; WinMapWindowPoints(hWnd, HWND_DESKTOP, &Pointl, 1); temp = sizeof(POINTL); PrfWriteProfileData(hini, pAppname, pKeyname, &Pointl, temp); WinPostMsg(hWnd, WM_QUIT, 0L, 0L); break; default: Handled = (msg == WM_COMMAND); break; } break; // forget this break and you are in dead trouble !!! default: Handled = FALSE; break; } if (!Handled) mReturn = WinDefDlgProc (hWnd, msg, mp1, mp2); return (mReturn); }
static void timer(HWND hwnd) { ICQFRAME *cfg = WinQueryWindowPtr(hwnd,0); int xMove = 0; int yMove = 0; SWP swp; ULONG flag = 0; POINTL p = { cfg->xMouse, cfg->yMouse }; if( ((USHORT) cfg->xMouse) == 0xFFFF || ((USHORT)cfg->yMouse) == 0xFFFF) return; WinMapWindowPoints(hwnd, HWND_DESKTOP, &p, 1); hwnd = WinQueryWindow(hwnd,QW_PARENT); WinQueryWindowPos(hwnd, &swp); if(cfg->xPos != 0xFFFF) { if(cfg->flags & ICQFRAME_FLAG_MOVEX) { xMove = p.x-cfg->xPos; swp.x += xMove; flag |= SWP_MOVE; } else { xMove = cfg->xPos - p.x; } if(cfg->flags & ICQFRAME_FLAG_SETCX) { swp.cx -= xMove; flag |= SWP_SIZE; } cfg->xPos = p.x; } if(cfg->yPos != 0xFFFF) { if(cfg->flags & ICQFRAME_FLAG_MOVEY) { yMove = p.y - cfg->yPos; swp.y += yMove; flag |= SWP_MOVE; } else { yMove = cfg->yPos - p.y; } if(cfg->flags & ICQFRAME_FLAG_SETCY) { swp.cy -= yMove; flag |= SWP_SIZE; } cfg->yPos = p.y; } if(flag) WinSetWindowPos(hwnd, 0, swp.x, swp.y, swp.cx, swp.cy, flag); cfg->xMouse = cfg->yMouse = 0xFFFF; }
static MRESULT beginDrag(HWND hwnd, POINTS *p) { ICQFRAME *cfg = WinQueryWindowPtr(hwnd,0); RECTL rcl; POINTL ptl = { p->x, p->y }; CHKPoint(); DBGTrace(p->x); DBGTrace(p->y); cfg->xPos = cfg->yPos = 0xFFFF; WinMapWindowPoints(hwnd, HWND_DESKTOP, &ptl, 1); WinQueryWindowRect(hwnd, &rcl); rcl.xRight -= rcl.xLeft; rcl.yTop -= rcl.yBottom; DBGTrace(rcl.xRight); DBGTrace(rcl.yTop); if(p->y > (rcl.yTop - TOP_MARGIN) && (p->x < (rcl.xRight - RIGHT_MARGIN)) && (p->x > LEFT_MARGIN) ) { DBGMessage("Drag window"); cfg->yPos = ptl.y; cfg->xPos = ptl.x; cfg->flags |= ICQFRAME_FLAG_MOVEX|ICQFRAME_FLAG_MOVEY; } else { if(p->x < LEFT_MARGIN) { cfg->xPos = ptl.x; cfg->flags |= ICQFRAME_FLAG_SETCX|ICQFRAME_FLAG_MOVEX; CHKPoint(); } if(p->x > (rcl.xRight - RIGHT_MARGIN)) { CHKPoint(); cfg->xPos = ptl.x; cfg->flags |= ICQFRAME_FLAG_SETCX; } if(p->y < BOTTOM_MARGIN) { CHKPoint(); cfg->yPos = ptl.y; cfg->flags |= ICQFRAME_FLAG_SETCY|ICQFRAME_FLAG_MOVEY; } if(p->y > (rcl.yTop - TOP_MARGIN)) { CHKPoint(); cfg->yPos = ptl.y; cfg->flags |= ICQFRAME_FLAG_SETCY; } } DBGTracex(cfg->xPos); DBGTracex(cfg->yPos); if(cfg->xPos != 0xFFFF || cfg->yPos != 0xFFFF) { DBGTrace(cfg->xPos) DBGTrace(cfg->yPos); WinSetCapture(HWND_DESKTOP, hwnd); cfg->timer = WinStartTimer(WinQueryAnchorBlock(hwnd), hwnd, 1, 50); DBGTracex(cfg->timer); if(!cfg->timer) { DBGMessage("Error starting timer"); icqWriteSysLog(cfg->icq,PROJECT,"Failure starting size timer"); } } return (MRESULT) TRUE; }
/**************************************************************************** * ClientWndProc * * - Typical PM client window procedure. (see below) * * - Standard client window I/O * ****************************************************************************/ MRESULT EXPENTRY ClientWndProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2) { RECTL rcl; SWP swp; HPS hpsPaint; static HPS hps; /* Permanent HPS */ static INT cx, cy; /* Client window dimensions */ static BOOL bSlowUpdateNow = FALSE; /* Update toggle for asteroids * * and enemy which are slow. */ static POINTL ptlCenter; /* Center of client window */ switch (msg) { /* Recieved from WinCreateStdWindow */ case WM_CREATE: /* Get permanent PS for entire window */ hps = WinGetPS(hwnd); /* Load private Asteroid fonts from ASTEROID.DLL */ if (GpiLoadFonts(hab, "ASTEROID") != GPI_OK) { WinReleasePS(hps); WinAlarm(HWND_DESKTOP, WA_WARNING); WinMessageBox(HWND_DESKTOP,NULLHANDLE, "Please put ASTEROID.DLL in a directory in your LIBPATH.", "Error reading ASTEROID.DLL", 0,MB_ICONHAND|MB_OK|MB_APPLMODAL); WinPostMsg(hwnd,WM_QUIT,(MPARAM) 0L,(MPARAM) 0L); return (MRESULT) TRUE; } /* Register/create logical fonts for use */ InitFonts(hps); /* Display About dialoge box */ WinDlgBox(HWND_DESKTOP, hwnd, (PFNWP)AboutDlgProc, NULLHANDLE, IDD_ABOUT, NULL); return 0; /* Recieved during attract mode when user starts game */ case WM_STARTGAME: /* Determine the number of players */ cPlayers = (INT)LONGFROMMP(mp1); /* Initialize each player */ for (Player=0;Player<cPlayers;Player++) { Level[Player] = 1; Ships[Player] = prfProfile.iSHIPS; DeletePhotons(); InitAsteroids(); InitEnemy(); } /* Start with player 1 */ Player = 0; iGameMode = GAME_MODE_NEXT; iGameModeCnt = GAME_PAUSE_TIME-1; /* Hide the pointer if mouse controls are enabled */ ShowMouse(FALSE); /* Paint everything */ WinSendMsg(hwnd, WM_PAINT, MPVOID, MPVOID); return 0; /* Recieved at startup and at the completion of a game */ case WM_INITGAME: /* Make mouse visible if we hid it before */ ShowMouse(TRUE); /* Fix menu to reflect attract mode */ EnableMenuItem(hwndMenu, IDM_START, TRUE); EnableMenuItem(hwndMenu, IDM_STOP, FALSE); /* Initialize player and enemy data structures */ cPlayers = 0; Level[0] = 1; for (Player=0;Player<2;Player++) { Score[Player] = 0L; Ships[Player] = 0; DeletePhotons(); } Player = 0; /* Initialize asteroids (and enemy) for attract mode */ InitAsteroids(); InitEnemy(); /* Depending on whether ASTEROID was just started or a game just * * completed display the "High Score" or "Press 1 or 2" screen. */ if (SHORT1FROMMP(mp1) == 0) { iGameMode = GAME_MODE_INIT1; iGameModeCnt = GAME_INIT_TIME; } else { iGameMode = GAME_MODE_INIT2; iGameModeCnt = GAME_INIT_TIME; } /* Paint everything */ WinSendMsg(hwnd, WM_PAINT, MPVOID, MPVOID); return 0; /* Usually recieved from the system, sometime forced by the program to * * ensure the screen is not corrupt. */ case WM_PAINT: /* Clear entire window to insure no "droppings" */ WinQueryWindowRect(hwnd,&rcl); WinFillRect(hps, &rcl, CLR_BLACK); WinInvalidateRect(hwnd, &rcl, FALSE); /* Get the update region and paint it black */ hpsPaint = WinBeginPaint(hwnd, (HPS)NULL, &rcl); WinFillRect(hpsPaint, &rcl, CLR_BLACK); WinEndPaint(hpsPaint); /* Only in normal play mode should we draw the ship */ if ((iGameMode == GAME_MODE_PLAY) && (iShipMode[Player] != EXPLOSION) && (iShipMode[Player] != HYPERSPACE)) DrawShip(hps, cx, cy, DRAW_INIT); else if ((iGameMode == GAME_MODE_PLAY) && (iShipMode[Player] == EXPLOSION)) ExplodeShip(hps, cx, cy); /* Draw the enemy if it is on the screen */ if (iEnemyMode[Player] != NONE) if (iEnemyMode[Player] != EXPLOSION) DrawEnemy(hps, cx, cy,DRAW_INIT); else ExplodeEnemy(hps, cx, cy); /* Draw photons and asteroids in all modes but the "Enter your * * initials" mode, otherwise draw that screen. */ if (iGameMode != GAME_MODE_HIGH) { DrawPhotons(hps, cx, cy, DRAW_INIT); DrawAsteroids(hps, cx, cy, DRAW_INIT); } else DrawHighScore(hps, cx, cy, DRAW_INIT); /* Always draw the score */ DrawScore(hps, cx, cy, DRAW_INIT); return 0; /* Left mouse button down. This simulates the move/track function * * in the system menu. */ case WM_BUTTON1DOWN: if (prfProfile.bMOUSECONTROL && iGameMode != GAME_MODE_INIT1 && iGameMode != GAME_MODE_INIT2 && !TogglePause(CHECK)) { UPDATE_FIRE(iShipMode[Player], TRUE); return (MRESULT)TRUE; } return WinSendMsg(hwndFrame, WM_TRACKFRAME, (MPARAM) (SHORT1FROMMP(mp2) | TF_MOVE), MPVOID); case WM_BUTTON1UP: if (prfProfile.bMOUSECONTROL) { UPDATE_FIRE(iShipMode[Player], FALSE); return (MRESULT)TRUE; } return 0; /* Left mouse button double clicked. Toggle frame control display. */ case WM_BUTTON1DBLCLK: if (!prfProfile.bMOUSECONTROL || iGameMode == GAME_MODE_INIT1 || iGameMode == GAME_MODE_INIT2 || TogglePause(CHECK)) { if (prfProfile.bCONTROLS = !prfProfile.bCONTROLS) ShowFrameControls(); else HideFrameControls(); } return 0; case WM_BUTTON2DOWN: if (prfProfile.bMOUSECONTROL) { UPDATE_SHIELD(iShipMode[Player], iShipShieldCnt[Player]); return (MRESULT)TRUE; } return 0; case WM_BUTTON2CLICK: if (prfProfile.bMOUSECONTROL) { UPDATE_HYPERSPACE(iShipMode[Player], iShipModeCnt[Player]); return (MRESULT)TRUE; } return 0; /* Right mouse button double clicked. Display the about dialog box. */ case WM_BUTTON2DBLCLK: if (!prfProfile.bMOUSECONTROL || iGameMode == GAME_MODE_INIT1 || iGameMode == GAME_MODE_INIT2 || TogglePause(CHECK)) { WinDlgBox(HWND_DESKTOP, hwndClient, (PFNWP)AboutDlgProc, NULLHANDLE, IDD_ABOUT, NULL); } return 0; /* User typed a key. Most of this is self explanatory. */ case WM_CHAR: ProcessChar((CHAR) (CHARMSG(&msg)->vkey-1), CHARMSG(&msg)->fs & KC_VIRTUALKEY, (CHAR) (CHARMSG(&msg)->chr), (BOOL) !(CHARMSG(&msg)->fs & KC_KEYUP)); return 0; /* User entered a command via the menu bar. */ case WM_COMMAND: DoCommand(hwnd, msg, mp1, mp2); return 0; /* Suspend/un-suspend game depending on focus */ case WM_SETFOCUS: if ((BOOL) SHORT1FROMMP(mp2)) TogglePause(SUSPEND_OFF); else if (!prfProfile.bBACKGRND) TogglePause(SUSPEND_ON); return 0; /* Keep track of the client window size. Profile information is not * * updated here because there are better places (i.e. at exit) */ case WM_SIZE: cx = (INT)SHORT1FROMMP(mp2); cy = (INT)SHORT2FROMMP(mp2); /* Keep track of client window position. Also updates profile info. */ case WM_MOVE: WinQueryWindowPos(hwndFrame,&swp); if (!(swp.fl & SWP_MAXIMIZE) && !(swp.fl & SWP_MINIMIZE)) { prfProfile.x = swp.x;prfProfile.y = swp.y; prfProfile.cx = swp.cx;prfProfile.cy = swp.cy; } if (swp.fl & SWP_MINIMIZE) if (!prfProfile.bBACKGRND) { /* Set icon */ WinSendMsg(hwndFrame, WM_SETICON, (MPARAM) WinLoadPointer(HWND_DESKTOP, NULLHANDLE, ID_RESOURCE), MPVOID); TogglePause(SUSPEND_ON); } else WinSendMsg(hwndFrame, WM_SETICON, MPVOID, MPVOID); else TogglePause(SUSPEND_OFF); ptlCenter.x = swp.cx / 2; ptlCenter.y = swp.cy / 2; WinMapWindowPoints(hwndClient, HWND_DESKTOP, &ptlCenter, 1L); return 0; /* Recieved approximately 31 times a second. This is the longest and * * ugliest of the messages, partly because there are so many cases * * to keep track of, partly because it must be highly optimized. */ case WM_TIMER: if (prfProfile.bMOUSECONTROL && iGameMode != GAME_MODE_INIT1 && iGameMode != GAME_MODE_INIT2) { POINTL ptl; static BOOL bUp, bLeft, bRight; WinQueryPointerPos(HWND_DESKTOP, &ptl); if (bUp || (ptl.y - ptlCenter.y > 0)) UPDATE_THRUST(iShipMode[Player], bUp = (ptl.y - ptlCenter.y > 0)); if (bLeft || (ptlCenter.x - ptl.x > 0)) UPDATE_LEFT(iShipMode[Player], bLeft = (ptlCenter.x - ptl.x > 0)); if (bRight || (ptlCenter.x - ptl.x < 0)) UPDATE_RIGHT(iShipMode[Player], bRight = (ptlCenter.x - ptl.x < 0)); WinSetPointerPos(HWND_DESKTOP, ptlCenter.x, ptlCenter.y); } /* Determine the current game mode */ switch (iGameMode) { /* Either initialization/attract mode screen. */ case GAME_MODE_INIT1: case GAME_MODE_INIT2: /* Switch screens when count expires */ if (--iGameModeCnt == 0) { if (iGameMode == GAME_MODE_INIT1) iGameMode = GAME_MODE_INIT2; else iGameMode = GAME_MODE_INIT1; iGameModeCnt = GAME_INIT_TIME; /* Score must be redrawn because the attract mode screens * * draw the score differently. */ DrawScore(hps, cx, cy, DRAW_REINIT); } /* Update photons, asteroids, enemy, and score */ UpdatePhotons(hps, cx, cy); if (uiSpeed == SPEED_OS2 || (bSlowUpdateNow = !bSlowUpdateNow)) { UpdateAsteroids(hps, cx, cy); UpdateEnemy(hps, cx, cy); DrawScore(hps, cx, cy, DRAW_REFRESH); } break; /* Completion of one player's turn or new game */ case GAME_MODE_NEXT: /* Initially, erase and redraw everything for new player */ if (iGameModeCnt-- == GAME_PAUSE_TIME) { if ((cPlayers == MAXPLAYERS) && (Ships[(Player+1) % MAXPLAYERS])) { DrawAsteroids(hps, cx, cy, DRAW_ERASE); DrawPhotons(hps, cx, cy, DRAW_ERASE); Player = (Player+1) % MAXPLAYERS; } DrawScore(hps, cx, cy, DRAW_REINIT); DrawAsteroids(hps, cx, cy, DRAW_INIT); } /* During countdown update score and asteroids */ else if (iGameModeCnt > 0) { if (uiSpeed == SPEED_OS2 || (bSlowUpdateNow = !bSlowUpdateNow)) { DrawScore(hps, cx, cy, DRAW_REFRESH); UpdateAsteroids(hps, cx, cy); } } /* At end of countdown start the player */ else { InitShip(); InitEnemy(); iGameMode = GAME_MODE_PLAY; DrawScore(hps, cx, cy, DRAW_REINIT); } break; /* Normal play mode */ case GAME_MODE_PLAY: /* Update ship, photons, asteroids, enemy, and score */ UpdateShip(hps, cx, cy); UpdatePhotons(hps, cx, cy); if (uiSpeed == SPEED_OS2 || (bSlowUpdateNow = !bSlowUpdateNow)) { UpdateAsteroids(hps, cx, cy); UpdateEnemy(hps, cx, cy); /* Erase old and draw new scores if there is a change*/ if (bChangeScore) { bChangeScore = FALSE; DrawScore(hps, cx, cy, DRAW_REINIT); } /* Else just refresh the score */ else DrawScore(hps, cx, cy, DRAW_REFRESH); } break; /* Game over mode. This is the longest and ugliest case because * * conditions are highly dependent on the number of players, * * multiplayer game status, and the number and order of high * * scores. */ case GAME_MODE_OVER: /* Initially, just update the score and number of ships */ if (iGameModeCnt-- == GAME_PAUSE_TIME) DrawScore(hps, cx, cy, DRAW_REINIT); /* During countdown refresh the score and update the asteroids */ else if (iGameModeCnt > 0) { if (uiSpeed == SPEED_OS2 || (bSlowUpdateNow = !bSlowUpdateNow)) { DrawScore(hps, cx, cy, DRAW_REFRESH); UpdateAsteroids(hps, cx, cy); } } /* At the end of the countdown, if there are any other players, * * continue with them. */ else { /* Countinue on with any remaining players. */ if ((cPlayers == MAXPLAYERS) && (Ships[(Player+1) % MAXPLAYERS])) { /* Erase all of the old asteroids. */ DrawAsteroids(hps, cx, cy, DRAW_ERASE); /* Setup everything for the next player */ Player = (Player+1) % MAXPLAYERS; InitShip(); InitEnemy(); iGameMode = GAME_MODE_PLAY; DrawAsteroids(hps, cx, cy, DRAW_INIT); DrawScore(hps, cx, cy, DRAW_REINIT); } /* Check for new high scores and update table as necessary. */ else { /* Erase all of the old asteroids. */ DrawAsteroids(hps, cx, cy, DRAW_ERASE); /* The following if/else block is admittedly a kludge, it is * * simple and it does work, however. Ideally it should * * sort the high scores and update the high score table in * * descending order. */ /* If player 1 scored higher than player 2 then check * * player 1 first for a high score. */ if (Score[0] > Score[1]) for (Player=0;Player<cPlayers;Player++) /* If the player's score is > than the lowest, * * update the high score table. */ if (Score[Player] > prfProfile.lSCORES[9]) { UpdateHighScores(); iGameMode = GAME_MODE_HIGH; } /* Otherwise, make sure he is not asked for his * * initials. */ else Score[Player] = 0; /* Otherwise, check player 2 first */ else for (Player=cPlayers;Player>=0;Player--) /* If the player's score is > than the lowest, * * update the high score table. */ if (Score[Player] > prfProfile.lSCORES[9]) { UpdateHighScores(); iGameMode = GAME_MODE_HIGH; } /* Otherwise, make sure he is not asked for his * * initials. */ else Score[Player] = 0L; /* If there was no high score, go into attract mode */ if (iGameMode != GAME_MODE_HIGH) WinSendMsg(hwnd,WM_INITGAME,MPFROMSHORT(1),(MPARAM) 0L); /* Else, check for player 1's initials first then 2's * * This is not faithful, in the arcade game the player * * with the higher score always goes first. */ else { if (Score[0] > 0L) Player = 0; else Player = 1; DrawScore(hps, cx, cy, DRAW_REINIT); DrawHighScore(hps, cx, cy, DRAW_INIT); } } } break; /* Mode which prompts players to enter their initials */ case GAME_MODE_HIGH: /* If the player's position is > 0 then refresh the screen */ if (Score[Player] > 0L) DrawHighScore(hps, cx, cy, DRAW_REFRESH); /* Else, the current player is done go to the next */ else if ((cPlayers == MAXPLAYERS) && (Player == 0) && (Score[1] > 0L)) { Player++; DrawHighScore(hps, cx, cy, DRAW_REINIT); } /* If there are no more high scores then go into attract mode */ else WinSendMsg(hwnd, WM_INITGAME, MPFROMSHORT(1), MPVOID); break; } return 0; /* Used by help manager */ case HM_QUERY_KEYS_HELP: return((MRESULT)IDH_CLIENTKEYS); /* Recieved always from the system or in the case of an initialization* * error. Both messages will normally save the profile information.* * Ideally the profile section should be moved to a subroutine and the* * the following should be broken into two distinct cases. */ case WM_SAVEAPPLICATION: case WM_DESTROY: /* If the fonts were not found bApplicationOk will be false, in * * that case the window profile information should not be updated.*/ if (TRUE) { /* Copy window position and size info into profile structure */ WinQueryWindowPos(hwndFrame, &swp); if (swp.fl & SWP_MAXIMIZE) prfProfile.ulMINMAX = SWP_MAXIMIZE; else if (swp.fl & SWP_MINIMIZE) prfProfile.ulMINMAX = SWP_MINIMIZE; else { prfProfile.ulMINMAX = 0; prfProfile.x = swp.x;prfProfile.y = swp.y; prfProfile.cx = swp.cx;prfProfile.cy = swp.cy; } /* Write profile information */ PrfWriteProfileData(HINI_USERPROFILE, szClientClass, "Data", &prfProfile, sizeof(PROFILEREC)); } /* If the application is terminating release the fonts and the hps. */ if (msg == WM_DESTROY) { /* Make sure mouse is visible if we hid it before */ ShowMouse(TRUE); /* Release font identifiers and DLL resource module */ GpiSetCharSet(hps, LCID_DEFAULT); GpiDeleteSetId(hps, LCID_LARGE); GpiDeleteSetId(hps, LCID_SMALL); GpiUnloadFonts(hab, "ASTEROID"); /* Release the "permanent" presentation space */ WinReleasePS(hps); } return 0; } return WinDefWindowProc(hwnd, msg, mp1, mp2); }
MRESULT EXPENTRY WndProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2 ) { // static POINTS DragStartPtrPos; POINTL ptl; static char Row, Col; static BOOL HasMoved = FALSE; static BOOL IntroSoundPlayed = FALSE; static BOOL RealPaint = TRUE; // indicates whether the board // has to be repainted or just copied INT aktscan; CHAR msgtext[256]; ULONG ulResponse; // ERRORID errId; switch( msg ){ case WM_CREATE: if( !InfoData.LoadHigh() ){ // get previously saved highscores InfoData.ResetHigh(); WinMessageBox( HWND_DESKTOP, hwndMain, "The file scores.dat " \ "(which is in the current directory) was somehow corrupted." \ " All Highscores will be reset to Zero.", "Error when loading Highscores", 0, MB_OK | MB_INFORMATION ); } // allocate memory for global variables; see GLOBALS struct in tgraph.h pg = new GLOBALS; // initialize globals to zero memset( pg, 0, sizeof( GLOBALS )); // store globals pointer into client window words; see WinRegisterClass // WinSetWindowULong( hwnd, QWL_USER, (ULONG) pg ); wcprintf("1: %x", WinGetLastError( hab ) ); DosCreateEventSem( NULL, &hevWaitAfterScan, 0, FALSE ); // Sem is created in reset state DosCreateEventSem( NULL, &hevHiScoreWin, 0, FALSE ); DosCreateEventSem( NULL, &hevWaitAfterSound, 0, FALSE ); DosCreateEventSem( NULL, &hevWaitSoundReady, 0, TRUE ); // Sem is created in posted state // hevWaitAfterScan and hewWaitAfterSound are used to indicate // when the respective WM_CREATE routines are done. // after that they are in posted state, as desired // initialize globals with important data pg->hab = hab; pg->hwndClient = hwnd; pg->hwndFrame = WinQueryWindow( hwnd, QW_PARENT ); pg->hwndTitlebar = WinWindowFromID( pg->hwndFrame, FID_TITLEBAR ); pg->hwndMenubar = WinWindowFromID( pg->hwndFrame, FID_MENU ); // create graphics and sound threads pg->tidTSound = _beginthread( &threadsound, NULL, LEN_STACK, NULL ); pg->tidTGraph = _beginthread( &threadgraph, NULL, LEN_STACK, NULL ); DosWaitEventSem( hevWaitAfterSound, SEM_INDEFINITE_WAIT ); WinPostMsg( pg->hwndTSound, WM_SOUND_INTRO, MPFROMHWND(hwnd), 0 ); // wait for the sound's WM_CREATE DosWaitEventSem( hevWaitAfterScan, SEM_INDEFINITE_WAIT ); // wait for the graphics' WM_CREATE InfoData.ShipsNotFound = GBoard.GetShipNumber(); wcprintf("create: %x", WinGetLastError( hab ) ); return (MRESULT)0; case WM_CONTROL: break; case WM_QUIT: break; case WM_CLOSE: // this message is sent before WM_QUIT InfoData.SaveHigh( WinGetCurrentTime(hab) ); // save the highscores and provide a random seed // get pointer to globals from window words // pg = (PGLOBALS) WinQueryWindowULong( hwnd, QWL_USER ); // tell object windows to quit, then exit their threads // WinSendMsg( pg->hwndTGraph, WM_DESTROY, mp1, mp2 ); WinPostMsg( pg->hwndTGraph, WM_QUIT, mp1, mp2 ); // WinSendMsg( pg->hwndTSound, WM_DESTROY, mp1, mp2 ); WinPostMsg( pg->hwndTSound, WM_QUIT, mp1, mp2 ); DosCloseEventSem( hevWaitAfterScan ); DosCloseEventSem( hevHiScoreWin ); DosCloseEventSem( hevWaitAfterSound ); DosCloseEventSem( hevWaitSoundReady ); WriteProfile( hab ); delete pg; return (MRESULT) 0; case WM_ERASEBACKGROUND: wcprintf("erasebackground"); // return (MRESULT) FALSE; return (MRESULT) TRUE; case WM_PAINT: /////////////////////////////////// { RECTL rectl; WinQueryWindowRect( pg->hwndClient, &rectl ); wcprintf("Linienrechteck: Breite: %d H”he: %d", rectl.xRight, rectl.yTop ); // test size: GpiSetColor( hpsGlob, CLR_RED ); ptl.x = rectl.xLeft; ptl.y = rectl.yBottom; GpiMove( hpsGlob, &ptl ); ptl.x = rectl.xRight; ptl.y = rectl.yTop; GpiLine( hpsGlob, &ptl ); } /////////////////////////// break; case WM_SIZE: wcprintf("main wnd function wm-size"); RealPaint = TRUE; GBoard.SetPMBoardValues( SHORT1FROMMP( mp2 ), SHORT2FROMMP( mp2 ) ); WndResize( hwnd ); wcprintf("size: %x", WinGetLastError( hab ) ); break; case WM_BEGINDRAG: WinSetCapture( HWND_DESKTOP, hwnd ); // capture the mouse pointer GBoard.SetfDrag( TRUE ); // indicate that mouse is being dragged GBoard.ResetFirstDraw(); // for initialization of drag op. fHideSquare = TRUE; WinSendMsg( pg->hwndTGraph, WM_SHOWPOINTERPOS, MPFROMHWND(hwnd), MPFROM2SHORT( 0, 0 ) ); // GBoard.ShowPointerPos( hwnd, 0, 0 ); // removes the square ptl.x = SHORT1FROMMP(mp1); ptl.y = SHORT2FROMMP(mp1); Row = GBoard.GetBoardRow( ptl.y ); // starting point of drag Col = GBoard.GetBoardCol( ptl.x ); // operation; static! return (MRESULT)TRUE; case WM_MOUSEMOVE: if( GBoard.GetfDrag() ){ // if mouse is being dragged WinSendMsg( pg->hwndTGraph, WM_DRAWDRAGLINE, mp1, MPFROM2SHORT( Row, Col ) ); HasMoved = TRUE; } else { // mouse is moved normally if( !fHideSquare ) WinSendMsg( pg->hwndTGraph, WM_SHOWPOINTERPOS, MPFROMHWND(hwnd), mp1 ); // GBoard.ShowPointerPos( hwnd, SHORT1FROMMP(mp1), // SHORT2FROMMP(mp1)); } break; case WM_ENDDRAG: WinSetCapture( HWND_DESKTOP, NULLHANDLE ); // release the captured // mouse pointer if( HasMoved ){ // mousemove has actually been moved WinSendMsg( pg->hwndTGraph, WM_MARKDRAGLINE, MPFROM2SHORT( Row, Col ), 0 ); HasMoved = FALSE; } GBoard.SetfDrag( FALSE ); GBoard.ClearDrawPoint(); // because no square is drawn right now fHideSquare = FALSE; WinSendMsg( pg->hwndTGraph, WM_SHOWPOINTERPOS, MPFROMHWND(hwnd), mp1 ); // GBoard.ShowPointerPos( hwnd, SHORT1FROMMP(mp1), SHORT2FROMMP(mp1)); // draws square at the current ptr pos break; case WM_CHAR: // key was pressed if( SHORT2FROMMP( mp2 ) != VK_SPACE ) break; // only space is interesting if( GBoard.GetfDrag() ) break; // do nothing while dragging if( !GBoard.GetfShowLines() ){ // lines not visible yet GBoard.SetfShowLines( TRUE ); WinSendMsg( pg->hwndTGraph, WM_DISPLAYLINES, 0, 0 ); } break; case WM_BUTTON1CLICK: if( !InfoData.ShipsNotFound ) break; // game is finished ptl.x = (LONG)SHORT1FROMMP( mp1 ); ptl.y = (LONG)SHORT2FROMMP( mp1 ); Row = GBoard.GetBoardRow( ptl.y ); Col = GBoard.GetBoardCol( ptl.x ); if( !Row || !Col ) break; fHideSquare = TRUE; WinSendMsg( pg->hwndTGraph, WM_SHOWPOINTERPOS, MPFROMHWND(hwnd), MPFROM2SHORT( 0, 0 ) ); // GBoard.ShowPointerPos( hwnd, 0, 0 ); // hides pointer square if(( aktscan = GBoard.GetDiscovered( Row, Col )) != -1 ){ WinSendMsg( pg->hwndTGraph, WM_DRAWPMPLACE, MPFROMHWND(hwnd), MPFROMSH2CH( MAKESHORT(Row, Col), (CHAR)aktscan,(CHAR)TRUE)); // umstricken auf WinPostMsg // toggle Place display } else { // scan Place DosResetEventSem( hevWaitAfterScan, &ulResponse ); // DosBeep(500, 150 ); WinPostMsg( pg->hwndTGraph, WM_GRAPH_SCAN, MPFROMHWND(hwnd), MPFROM2SHORT( Row, Col ) ); // DosBeep( 800, 150 ); WinWaitEventSem( hevWaitAfterScan, SEM_INDEFINITE_WAIT ); // DosBeep( 1000, 150 ); // first the scanning sounds must be played (and finished) aktscan = GBoard.Scan( Row, Col ); if( aktscan == GBoard.GetShipNumber() + 10 ){ InfoData.ShipsNotFound--; WinPostMsg( pg->hwndTSound, WM_SOUND_FOUNDSHIP, MPFROMHWND(hwnd), 0 ); } else { if( aktscan ) WinPostMsg( pg->hwndTSound, WM_SOUND_FOUND, MPFROMHWND(hwnd), MPFROMLONG( aktscan ) ); else WinPostMsg( pg->hwndTSound, WM_SOUND_FOUND0, MPFROMHWND(hwnd), 0 ); } WinWaitEventSem( hevWaitAfterScan, SEM_INDEFINITE_WAIT ); // waits until scanning is done, and only then displays the // field icon // hps = WinGetPS( hwnd ); WinSendMsg( pg->hwndTGraph, WM_DRAWPMPLACE, MPFROMHWND(hwnd), MPFROMSH2CH( MAKESHORT(Row, Col), (CHAR)aktscan,(CHAR)TRUE)); // umstricken auf WinPostMsg WinPostMsg( pg->hwndTGraph, WM_SHOWSTATUSLINE, 0, 0 ); // ShowStatusLine( hps, GBoard.MovesNeeded(), InfoData.ShipsNotFound, // GBoard.GetWinWidth(), GBoard.GetWinHeight() ); // WinReleasePS( hps ); if( !InfoData.ShipsNotFound ){ // game is finished, all ships found Score = GBoard.MovesNeeded(); if ( !InfoData.ReturnLastHigh() // still space in the hiscore table || Score < InfoData.ReturnLastHigh() ){ // player kicks last one out // player enters highscore table WinPostMsg( pg->hwndTSound, WM_SOUND_NEWHISCORE, MPFROMHWND(hwnd), 0 ); WinWaitEventSem( hevHiScoreWin, SEM_INDEFINITE_WAIT ); // waits until the NEWHISCORE sound is actually played WinDlgBox( HWND_DESKTOP, hwnd, HighScoreDlgProc, (HMODULE)0, IDR_HIGHSCOREDLG, NULL ); WinPostMsg( hwnd, WM_COMMAND, MPFROMSHORT(IDM_GAMEHIGH), (MPARAM)0 ); // show highscore-table DosResetEventSem( hevHiScoreWin, &ulResponse ); // resets the sem again } else { WinPostMsg( pg->hwndTSound, WM_SOUND_LOST, MPFROMHWND(hwnd), 0 ); WinWaitEventSem( hevHiScoreWin, SEM_INDEFINITE_WAIT ); // waits until the NEWHISCORE sound is actually played sprintf( msgtext, "You needed %d moves to find the lost ships. " \ "To enter the highscore list you need %d moves." \ " So try again!", Score, InfoData.ReturnLastHigh() - 1 ); WinMessageBox( HWND_DESKTOP, hwnd, msgtext, "Oh, Shit!", 0, MB_OK | MB_INFORMATION | MB_HELP ); } } } fHideSquare = FALSE; WinSendMsg( pg->hwndTGraph, WM_SHOWPOINTERPOS, MPFROMHWND(hwnd), MPFROM2SHORT( ptl.x, ptl.y ) ); // GBoard.ShowPointerPos( hwnd, ptl.x, ptl.y ); // redisplay ptr square break; case WM_BUTTON2CLICK: fHideSquare = TRUE; WinSendMsg( pg->hwndTGraph, WM_SHOWPOINTERPOS, MPFROMHWND(hwnd), MPFROM2SHORT( 0, 0 ) ); ptl.x = (LONG)SHORT1FROMMP( mp1 ); ptl.y = (LONG)SHORT2FROMMP( mp1 ); Row = GBoard.GetBoardRow( ptl.y ); Col = GBoard.GetBoardCol( ptl.x ); WinSendMsg( pg->hwndTGraph, WM_DRAWPMMARK, MPFROMHWND(hwnd), MPFROM2SHORT( Row, Col ) ); fHideSquare = FALSE; WinSendMsg( pg->hwndTGraph, WM_SHOWPOINTERPOS, MPFROMHWND(hwnd), MPFROM2SHORT( ptl.x, ptl.y ) ); break; case WM_COMMAND: switch( SHORT1FROMMP( mp1 ) ){ case IDM_GAMENEW: GBoard.NewGame(); InfoData.ShipsNotFound = GBoard.GetShipNumber(); RealPaint = TRUE; WinInvalidateRect( hwnd, NULL, TRUE ); break; case IDM_GAMESETTINGS: if( WinDlgBox( HWND_DESKTOP, hwndFrame, GameSettingsDlgProc, (HMODULE)0, IDR_GAMESETTINGSDLG, NULL ) ){ // screen must be repainted RealPaint = TRUE; WinInvalidateRect( hwnd, NULL, TRUE ); } break; case IDM_GAMEHIGH: if( !WinDlgBox( HWND_DESKTOP, hwndFrame, ShowHighDlgProc, (HMODULE)0, IDR_SHOWHIGHDLG, NULL ) ){ // user requested "Clear" if( WinMessageBox( HWND_DESKTOP, hwndMain, "Do you really want to eradicate all those " \ "arduously achieved highscores?", "Clear Highscores", 0, MB_OKCANCEL | MB_WARNING ) == MBID_OK ) InfoData.ResetHigh(); } break; case IDM_HELPINDEX: // help index WinSendMsg( hwndHelp, HM_HELP_INDEX, 0, 0 ); break; case IDM_HELPGENERAL: // general help WinSendMsg( hwndHelp, HM_EXT_HELP, 0, 0 ); break; case IDM_HELPEXTENDED: // help on help (system page) WinSendMsg( hwndHelp, HM_DISPLAY_HELP, 0, 0 ); break; case IDM_HELPKEYS: // keys help WinSendMsg( hwndHelp, HM_KEYS_HELP, 0, 0 ); break; case IDM_HELPPRODUCTINFO: ulResponse = WinDlgBox( HWND_DESKTOP, hwndFrame, ProdInfoDlgProc, (HMODULE)0, IDR_PRODINFODLG, NULL ); break; } break; case HM_QUERY_KEYS_HELP: // system asks which page to display return MRFROMSHORT( PANEL_HELPKEYS ); case HM_HELPSUBITEM_NOT_FOUND: return (MRESULT)FALSE; case WM_USER_ACK: // graphics task finished its work // DosBeep( 1000, 150 ); switch( (ULONG)mp1 ){ case WM_USER_PAINT: WinQueryPointerPos( HWND_DESKTOP, &ptl ); WinMapWindowPoints( HWND_DESKTOP, hwnd, &ptl, 1); fHideSquare = FALSE; WinSendMsg( pg->hwndTGraph, WM_SHOWPOINTERPOS, MPFROMHWND(hwnd), MPFROM2SHORT( ptl.x, ptl.y ) ); // GBoard.ShowPointerPos( hwnd, ptl.x, ptl.y ); // painting has finished, square can be displayed now break; } break; case WM_SOUND_ACK: switch( (ULONG)mp1 ){ case WM_SOUND_INTRO: break; } break; default: return (MRESULT)WinDefWindowProc( hwnd, msg, mp1, mp2 ); } // end switch( msg ) return (MRESULT)WinDefWindowProc( hwnd, msg, mp1, mp2 ); } // end MRESULT EXPENTRY WndProc()
/*----------------------------------------------------------------------*/ SHORT DMLBLocateListboxItem( HWND hwnd, HWND RelHwnd, SHORT Y, SHORT Option ) /*----------------------------------------------------------------------*/ /* Parameters: */ /* hwnd Listbox of interest */ /* RelHwnd Window to which Y is relative to */ /* Y Y position of the pointer */ /* Option LLI_UNDER to return index of item under pointer, */ /* LLI_INSERTPOINT to index of item nearest insert point */ /*----------------------------------------------------------------------*/ /* Given a Y window coordinate, this function will calculate the item */ /* number of the listbox item at that position. The LLI_UNDER option */ /* will return the item directly under the pointer. The LLI_INSERTPOINT*/ /* option will return the item number *before* which an insertion should*/ /* be made (drop zones are calculated as the half-way points through */ /* each item). */ /*----------------------------------------------------------------------*/ { RECTL Rect; POINTL Points[2]; HPS hps; LONG VertSize; SHORT ItemNum; char ClassName[10]; /* Map coordinate from window it is relative to, to win of interst*/ Points[0].x = 0; Points[0].y = Y; WinMapWindowPoints(RelHwnd, hwnd, &(Points[0]), 1L); Y = Points[0].y; /* If this is actually a MultiColumn ListBox, we must find the */ /* real listbox which is the first column and use it for our */ /* location calculations. Since we only care about the Y */ /* coordinate we only need to look at the 1st column of the MCLB. */ WinQueryClassName(hwnd, sizeof(ClassName), ClassName); if (!strcmp("MCLBCls", ClassName)) hwnd = WinWindowFromID(hwnd, 1); /* Get handle of 1st column's listbox */ /* If this is an OWNERDRAW listbox, ask owner how big items are. */ VertSize = 0; if (WinQueryWindowULong(hwnd, QWL_STYLE) & LS_OWNERDRAW) VertSize = SHORT1FROMMR( // Take returned Height WinSendMsg(WinQueryWindow(hwnd, QW_OWNER), // Query owner of listbox WM_MEASUREITEM, // Ask owner the size MPFROMSHORT(WinQueryWindowUShort(hwnd, QWS_ID)), // Listbox ID MPFROMSHORT(0))); // First item if (VertSize == 0) { /* For a normal listbox, items are the size of the font. To */ /* determine the size we get the bounding box of a space. */ hps = WinGetPS(hwnd); GpiQueryTextBox(hps, 1L, " ", 2, Points); VertSize = Points[TXTBOX_TOPLEFT].y - Points[TXTBOX_BOTTOMLEFT].y; WinReleasePS(hps); } WinQueryWindowRect(hwnd, &Rect); Rect.yTop = Rect.yTop-2; /* Listbox frame is 2 pixels */ /* Calculate item number of item under the pointer */ ItemNum = (SHORT)WinSendMsg(hwnd, LM_QUERYTOPINDEX, 0L, 0L) + ((Rect.yTop-Y)/VertSize); /* Return item under pointer, or insertion point */ switch (Option) { case LLI_UNDER: return ItemNum; case LLI_INSERTPOINT: if (((Rect.yTop-Y) % VertSize) <= (VertSize / 2)) return ItemNum; return ItemNum+1; /* Note: May exceed num of items in list */ } }
MRESULT EXPENTRY fnConfigDialogProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2) { HWND hwndOwner; SWP swpDlg, swpOwner; POINTL ptlTemp; ConfigDlgInitParams_p pCfgDlgInit; switch (msg) { case WM_INITDLG: // Store window instance data pointer in window words WinSetWindowULong(hwnd, QWL_USER, (ULONG) mp2); pCfgDlgInit = (ConfigDlgInitParams_p) mp2; // Set dialog control texts and fonts based on // current language internal_SetPageFont(hwnd); internal_SetConfigDialogText(hwnd, pCfgDlgInit->pchHomeDirectory); // Set initial position of dialog window and show it WinQueryWindowPos(hwnd, &swpDlg); hwndOwner = WinQueryWindow(hwnd, QW_OWNER); WinQueryWindowPos(hwndOwner, &swpOwner); ptlTemp.x = swpOwner.x; ptlTemp.y = swpOwner.y; WinMapWindowPoints(WinQueryWindow(hwndOwner, QW_PARENT), HWND_DESKTOP, &ptlTemp, 1); WinSetWindowPos(hwnd, HWND_TOP, ptlTemp.x + (swpOwner.cx - swpDlg.cx)/2, ptlTemp.y + (swpOwner.cy - swpDlg.cy)/2, 0, 0, SWP_MOVE | SWP_SHOW); //setup the dialog WinSendDlgItemMsg(hwnd, EF_TEXT, EM_SETTEXTLIMIT, MPFROMSHORT(256), NULL); WinSetWindowText(WinWindowFromID(hwnd, EF_TEXT), pCfgDlgInit->pchText); internal_AdjustConfigDialogControls(hwnd); return (MRESULT) FALSE; case WM_COMMAND: switch (SHORT1FROMMP(mp1)) { case PB_CONFOK: pCfgDlgInit = (ConfigDlgInitParams_p) WinQueryWindowULong(hwnd, QWL_USER); if (pCfgDlgInit) { char buff[255]; buff[0]= '\0'; WinQueryWindowText(WinWindowFromID(hwnd, EF_TEXT), 248, &buff); strcpy(pCfgDlgInit->pchText, buff); /*AddLog(buff); AddLog(pCfgDlgInit->pchText);*/ } break; case PB_CONFCANCEL: // restore the old image pCfgDlgInit = (ConfigDlgInitParams_p) WinQueryWindowULong(hwnd, QWL_USER); if (pCfgDlgInit) { } break; } break; default: break; } return WinDefDlgProc(hwnd, msg, mp1, mp2); }
/*----------------------------------------------------------------------*/ void DMLBCheckTargetLocation(HWND SrcHwnd, DMLBData *InstData, SHORT X, SHORT Y) /*----------------------------------------------------------------------*/ /* X,Y is in SrcHwnd window coordinates. */ /* Given an Y,Y coordinate of the pointer, determine if the pointer is */ /* over a listbox that will accept a drop. If it is, we save the */ /* handle of the listbox and set the PrevLocation to POINT_INSIDE in */ /* the instance data. Otherwise, we see if the position is near the */ /* top/bottom edge of the last good target listbox we had. If so, set */ /* the PrevLocation to POINT_NORTH/SOUTH as appropriate. Finally, if */ /* none of the above, just set the PrevLocation to POINT_OUTSIDE. */ /*----------------------------------------------------------------------*/ { RECTL Rect; POINTL ScreenPoint; HWND OverHwnd; char OverClass[10]; InstData->PrevLocation = POINT_OUTSIDE; // Assume this until we know otherwise /* See if window under the pointer is a listbox. */ ScreenPoint.x = X; ScreenPoint.y = Y; WinMapWindowPoints(SrcHwnd, HWND_DESKTOP, &ScreenPoint, 1L); OverHwnd = WinWindowFromPoint(HWND_DESKTOP, &ScreenPoint, TRUE); WinQueryClassName(OverHwnd, sizeof(OverClass), OverClass); if (!strcmp(OverClass, LISTBOX_CLASS_STRING)) { /* Yes, it is a listbox -- see if it will accept our drop */ MRESULT Answer; /* If this is part of an MCLB, the MCLB is really the target */ WinQueryClassName(WinQueryWindow(OverHwnd, QW_OWNER), sizeof(OverClass), OverClass); if (!strcmp(OverClass, "MCLBCls")) OverHwnd = WinQueryWindow(OverHwnd, QW_OWNER); Answer = WinSendMsg(WinQueryWindow(OverHwnd, QW_OWNER), WM_CONTROL, MPFROM2SHORT(WinQueryWindowUShort(OverHwnd, QWS_ID), LN_DMLB_QRYDROP), MPFROMHWND(SrcHwnd)); if ((BOOL)SHORT1FROMMR(Answer)) { /* Yes, it will accept the drop */ InstData->TargetHwnd = OverHwnd; // Note new target // if (SrcHwnd == OverHwnd) // InstData->TargetDropMode = DROPMODE_MOVE; // Force MOVE for same-listbox drops // else InstData->TargetDropMode = SHORT2FROMMR(Answer); // Copy, Move, or Delete InstData->PrevLocation = POINT_INSIDE; // We are inside the listbox now return; } /* It will not accept a drop, proceed as point outside */ return; } /* Not a listbox class window. See if pointer is near north/south */ /* edge of last good target listbox. ("Near" is defined as the */ /* height of a menu bar). */ WinQueryWindowRect(InstData->TargetHwnd, &Rect); /* Translate rectangle to screen coordinates */ WinMapWindowPoints(InstData->TargetHwnd, HWND_DESKTOP, (POINTL *)&Rect, 2L); if ((ScreenPoint.x >= Rect.xLeft) && (ScreenPoint.x <= Rect.xRight)) { if ((ScreenPoint.y < Rect.yTop + WinQuerySysValue(HWND_DESKTOP, SV_CYMENU)) && (ScreenPoint.y > Rect.yBottom - WinQuerySysValue(HWND_DESKTOP, SV_CYMENU))) { if (ScreenPoint.y > Rect.yTop) InstData->PrevLocation = POINT_NORTH; else if (ScreenPoint.y < Rect.yBottom) InstData->PrevLocation = POINT_SOUTH; return; } // Within a menu-size distance of north/south edge } // Within the horizontal boundries of the listbox /* Pointer is outside the range of interest */ return; }
MRESULT Window::stdWndProc( HWND hWnd, ULONG iMessage, MPARAM mParam1, MPARAM mParam2, BOOL *returned ) { switch( iMessage ) { // case WM_FOCUSCHANGE : case WM_SETSELECTION : case WM_ACTIVATE : { if( type != Window::LISTBOX && type != Window::COMBOLISTBOX ) { focus( (BOOL)mParam1 );//SHORT1FROMMP( mParam2 ) ); } break; } case WM_SETFOCUS : { if( type != Window::LISTBOX && type != Window::COMBOLISTBOX ) focusSet( (BOOL)mParam2 ); break; } case WM_BUTTON1DOWN : { if( type == SCROLLBAR ) setFocus(); HWND hwnd = WinQueryFocus( HWND_DESKTOP ); if( mouseListener.getSize() != 0 ) { mouseButtonDown = TRUE; WinSetCapture( HWND_DESKTOP, hWnd ); WinStartTimer( Application::hab, hWndClient, 1, 50 ); Point pos( SHORT1FROMMP(mParam1), SHORT2FROMMP(mParam1) ); performMouseEvent( &pos, AMouseEvent::LEFT, AMouseEvent::DOWN ); } if( hwnd != WinQueryFocus( HWND_DESKTOP ) ) return (MRESULT)TRUE; break; } case WM_BUTTON1UP : { if( type == LISTBOX || type == COMBOLISTBOX ) { performFocusEvent( (int)WinSendMsg( (HWND)mParam2, LM_QUERYSELECTION, MPARAM(0), MPARAM(NULL) ) ); } else if( mouseListener.getSize() != 0 ) { mouseButtonDown = FALSE; WinStopTimer( Application::hab, hWndClient, 1 ); WinSetCapture( HWND_DESKTOP, NULLHANDLE ); Point pos( SHORT1FROMMP(mParam1), SHORT2FROMMP(mParam1) ); performMouseEvent( &pos, AMouseEvent::LEFT, AMouseEvent::RELEASE ); // return (MPARAM)TRUE; } break; } case WM_BUTTON2DOWN : { if( mouseListener.getSize() != 0 ) { WinSetCapture( HWND_DESKTOP, hWnd ); WinStartTimer( Application::hab, hWndClient, 1, 50 ); Point pos( SHORT1FROMMP(mParam1), SHORT2FROMMP(mParam1) ); performMouseEvent( &pos, AMouseEvent::RIGHT, AMouseEvent::DOWN ); } break; } case WM_BUTTON2UP : { if( mouseListener.getSize() != 0 ) { WinStopTimer( Application::hab, hWndClient, 1 ); WinSetCapture( HWND_DESKTOP, NULLHANDLE ); Point pos( SHORT1FROMMP(mParam1), SHORT2FROMMP(mParam1) ); performMouseEvent( &pos, AMouseEvent::RIGHT, AMouseEvent::RELEASE ); } break; } case WM_BUTTON1CLICK : { if( mouseListener.getSize() != 0 ) { // Check if triple click int newTick = WinGetCurrentTime( Application::hab ); if( newTick - lastTick <= WinQuerySysValue( HWND_DESKTOP, SV_DBLCLKTIME ) ) { Point pos( SHORT1FROMMP(mParam1), SHORT2FROMMP(mParam1) ); performMouseEvent( &pos, AMouseEvent::LEFT, AMouseEvent::TRIPLECLICK ); } else { Point pos( SHORT1FROMMP(mParam1), SHORT2FROMMP(mParam1) ); performMouseEvent( &pos, AMouseEvent::LEFT, AMouseEvent::CLICK ); } } break; } case WM_BUTTON2CLICK : { if( mouseListener.getSize() != 0 ) { Point pos( SHORT1FROMMP(mParam1), SHORT2FROMMP(mParam1) ); performMouseEvent( &pos, AMouseEvent::RIGHT, AMouseEvent::CLICK ); } break; } case WM_BUTTON1DBLCLK : { if( mouseListener.getSize() != 0 ) { Point pos( SHORT1FROMMP(mParam1), SHORT2FROMMP(mParam1) ); performMouseEvent( &pos, AMouseEvent::LEFT, AMouseEvent::DOUBLECLICK ); } lastTick = WinGetCurrentTime( Application::hab ); break; } case WM_BUTTON2DBLCLK : { if( mouseListener.getSize() != 0 ) { Point pos( SHORT1FROMMP(mParam1), SHORT2FROMMP(mParam1) ); performMouseEvent( &pos, AMouseEvent::RIGHT, AMouseEvent::DOUBLECLICK ); } break; } case WM_MOUSEMOVE : { if( currentPointer != NULLHANDLE ) WinSetPointer( HWND_DESKTOP, currentPointer ); if( mouseListener.getSize() != 0 ) { Point pos( (SHORT)SHORT1FROMMP(mParam1), (SHORT)SHORT2FROMMP(mParam1) ); performMouseEvent( &pos, 0, AMouseEvent::MOVE ); } if( currentPointer != NULLHANDLE ) return (MPARAM)TRUE; break; } case WM_TIMER : { if( mouseButtonDown ) { POINTL ptl; WinQueryPointerPos( HWND_DESKTOP, &ptl ); WinMapWindowPoints( HWND_DESKTOP, hWnd, &ptl, 1 ); if( ptl.y < 0 || ptl.y > height ) { Point pos( ptl.x, ptl.y ); performMouseEvent( &pos, 0, AMouseEvent::MOVE ); } } break; } case WM_SIZE : { int oldWidth = width, oldHeight = height; SWP swp; WinQueryWindowPos( hWndFrame, &swp ); width = swp.cx; height = swp.cy; size( oldWidth, oldHeight ); break; } case WM_HSCROLL : { int pos = SHORT1FROMMP( mParam2 ), id = SHORT1FROMMP( mParam1 ); switch( SHORT2FROMMP( mParam2 ) ) { case SB_PAGERIGHT : { performScrollbarEvent( id, Scrollbar::PAGERIGHT, pos ); break; } case SB_PAGELEFT : { performScrollbarEvent( id, Scrollbar::PAGELEFT, pos ); break; } case SB_LINERIGHT : { performScrollbarEvent( id, Scrollbar::LINERIGHT, pos ); break; } case SB_LINELEFT : { performScrollbarEvent( id, Scrollbar::LINELEFT, pos ); break; } case SB_SLIDERTRACK : { performScrollbarEvent( id, Scrollbar::HORZTRACK, pos ); break; } case SB_SLIDERPOSITION : { performScrollbarEvent( id, Scrollbar::HORZRELEASED, pos ); break; } } break; } case WM_SYSCOMMAND : { // Check if the parent is a dialog, then chain the WM_SYSCOMMAND if( parent->getType() == DIALOG ) WinSendMsg( ((Window *)parent)->getHWND(), WM_SYSCOMMAND, mParam1, mParam2 ); break; } case WM_VSCROLL : { int id = SHORT1FROMMP( mParam1 ); Scrollbar *scrollbar = (Scrollbar *)getControl( id ); int pos; if( scrollbar ) pos = scrollbar->convertScrollPosToReal( SHORT1FROMMP( mParam2 ) ); else pos = SHORT1FROMMP( mParam2 ); switch( SHORT2FROMMP( mParam2 ) ) { case SB_PAGEDOWN : { performScrollbarEvent( id, Scrollbar::PAGEDOWN, pos ); break; } case SB_PAGEUP : { performScrollbarEvent( id, Scrollbar::PAGEUP, pos ); break; } case SB_LINEDOWN : { performScrollbarEvent( id, Scrollbar::LINEDOWN, pos ); break; } case SB_LINEUP : { performScrollbarEvent( id, Scrollbar::LINEUP, pos ); break; } case SB_SLIDERTRACK : { performScrollbarEvent( id, Scrollbar::VERTTRACK, pos ); break; } case SB_SLIDERPOSITION : { performScrollbarEvent( id, Scrollbar::VERTRELEASED, pos ); break; } } break; } case WM_MOVE : { SWP swp; WinQueryWindowPos( hWndFrame, &swp ); x = swp.x; y = swp.y; move(); break; } case WM_CLOSE : { if( close() ) break; else return (MPARAM)FALSE; } case WM_COMMAND : { if( SHORT1FROMMP( mParam2 ) == CMDSRC_PUSHBUTTON ) { Window *control = (Window *)getControl( SHORT1FROMMP(mParam1)); if( control != NULL ) { if( control->type == PUSHBUTTON ) { control->performButtonEvent( control, control->id ); return FALSE; } } else return FALSE; // In case ESC would close the dialog } break; } case WM_CHAR : { if( type == LISTBOX ) { performFocusEvent( (int)WinSendMsg( (HWND)mParam2, LM_QUERYSELECTION, MPARAM(0), MPARAM(NULL) ) ); } if( (SHORT1FROMMP( mParam1 ) & KC_KEYUP) || (SHORT1FROMMP( mParam1 ) & KC_DEADKEY) || (SHORT1FROMMP( mParam1 ) & KC_INVALIDCOMP) ) break; /* if( SHORT1FROMMP( mParam1 ) & KC_COMPOSITE ) mParam1 = MPFROM2SHORT( SHORT1FROMMP( mParam1 ) & ~KC_VIRTUALKEY, SHORT2FROMMP( mParam1 ) );*/ int modifiers = 0; if( SHORT1FROMMP( mParam1 ) & KC_SHIFT ) modifiers |= KeyDef::SHIFT; if( SHORT1FROMMP( mParam1 ) & KC_ALT ) modifiers |= KeyDef::kALT; if( SHORT1FROMMP( mParam1 ) & KC_CTRL) modifiers |= KeyDef::CTRL; if( SHORT1FROMMP( mParam1 ) & KC_VIRTUALKEY ) { int key = 0, vKey = SHORT2FROMMP( mParam2 ); // Maybe NumLock is on if( SHORT1FROMMP(mParam1) & KC_CHAR && !(vKey == VK_ENTER || vKey == VK_NEWLINE || vKey == VK_TAB || vKey == VK_BACKSPACE )) key = SHORT1FROMMP( mParam2 ); else if( vKey == VK_UP ) key = KeyDef::UP; else if( vKey == VK_DOWN ) key = KeyDef::DOWN; else if( vKey == VK_LEFT ) key = KeyDef::LEFT; else if( vKey == VK_RIGHT ) key = KeyDef::RIGHT; else if( vKey == VK_PAGEUP ) key = KeyDef::PAGEUP; else if( vKey == VK_PAGEDOWN ) key = KeyDef::PAGEDOWN; else if( vKey == VK_INSERT ) key = KeyDef::INSERT; else if( vKey == VK_DELETE ) key = KeyDef::kDELETE; else if( vKey == VK_HOME ) key = KeyDef::HOME; else if( vKey == VK_END ) key = KeyDef::END; else if( vKey == VK_ESC ) key = KeyDef::ESCAPE; else if( vKey == VK_F1 ) key = KeyDef::F1; else if( vKey == VK_F2 ) key = KeyDef::F2; else if( vKey == VK_F3 ) key = KeyDef::F3; else if( vKey == VK_F4 ) key = KeyDef::F4; else if( vKey == VK_F5 ) key = KeyDef::F5; else if( vKey == VK_F6 ) key = KeyDef::F6; else if( vKey == VK_F7 ) key = KeyDef::F7; else if( vKey == VK_F8 ) key = KeyDef::F8; else if( vKey == VK_F9 ) key = KeyDef::F9; else if( vKey == VK_F10 ) key = KeyDef::F10; else if( vKey == VK_F11 ) key = KeyDef::F11; else if( vKey == VK_F12 ) key = KeyDef::F12; else if( vKey == VK_ENTER ) key = KeyDef::ENTER; else if( vKey == VK_NEWLINE ) key = KeyDef::RETURN; else if( vKey == VK_BACKSPACE ) key = KeyDef::BACKSPACE; else if( vKey == VK_TAB ) key = KeyDef::TAB; else if( vKey == VK_BACKTAB ) { key = KeyDef::TAB; modifiers |= KeyDef::SHIFT; } else if( vKey == VK_SPACE ) key = KeyDef::SPACE; if( parent->getType() == DIALOG ) ((Dialog *)parent)->focusHotkey( key ); if( key != 0 ) if( performKeyEvent( this, modifiers, key ) ) return MPARAM(TRUE); // Do not pass up and down key to dialog if this is a combobox (would // move focus) /* if( getFilterDialogArrows() && (vKey == VK_UP || vKey == VK_DOWN) ) return (MPARAM)TRUE;*/ } else { int key = SHORT1FROMMP( mParam2 ); if( performKeyEvent( this, modifiers, key ) ) return MPARAM(TRUE); } break; } case WM_CONTROL : { Window *control = (Window *)getControl( SHORT1FROMMP(mParam1)); if( control != NULL ) { if( control->type == Window::LISTBOX || control->type == Window::COMBOLISTBOX ) { switch( SHORT2FROMMP(mParam1) ) { case LN_KILLFOCUS : control->focus( FALSE ); break; case LN_SETFOCUS : control->focus( TRUE );break; case LN_ENTER : control->performSelectionEvent( (int)WinSendMsg( (HWND)mParam2, LM_QUERYSELECTION, MPARAM(0), MPARAM(NULL) ) ); break; } } else if( control->type == Window::SCROLLBAR ) { switch( SHORT2FROMMP(mParam1) ) { case SLN_KILLFOCUS : control->focus( FALSE ); break; case SLN_SETFOCUS : control->setFocus(); break; } } else if( control->type == Window::RADIOBUTTON || control->type == Window::CHECKBOX ) { switch( SHORT2FROMMP( mParam1) ) { case BN_CLICKED : case BN_DBLCLICKED : control->performButtonEvent( control, control->id ); break; } } } break; } case DM_DRAGOVER: { PDRAGINFO pDInfo; PDRAGITEM pDItem; if( !acceptDropFiles ) return MRFROM2SHORT(DOR_NODROPOP, 0); pDInfo = (PDRAGINFO)mParam1; DrgAccessDraginfo(pDInfo); pDItem = DrgQueryDragitemPtr(pDInfo, 0); USHORT usOp = 0, usDrop = DOR_NEVERDROP; /* Inspect each item to see if it is acceptable */ ULONG ulItems = DrgQueryDragitemCount (pDInfo); for (INT i = 0; i < ulItems; i++) { pDItem = DrgQueryDragitemPtr(pDInfo, i); /* The item is acceptable only if it is copyable and the */ /* operation is a copy, or it is moveable and the operation */ /* is a move, and it can render <DRM_OS2FILE, NULL> */ if (pDItem->fsSupportedOps & DO_COPYABLE) { usOp = DO_COPY; /* Only check files, all types */ if (DrgVerifyRMF(pDItem, "DRM_OS2FILE", 0)) usDrop = DOR_DROP; else { usDrop = DOR_NEVERDROP; break; } } else { /* Must be a file but not droppable in type op */ usDrop = DOR_NODROPOP; usOp = 0; break; } } /* end for all items dragged */ DrgFreeDraginfo(pDInfo); return MRFROM2SHORT(usDrop, usOp); } case DM_DROP: { PDRAGINFO pDInfo; PDRAGITEM pDItem; pDInfo = (PDRAGINFO)mParam1; DrgAccessDraginfo(pDInfo); pDItem = DrgQueryDragitemPtr(pDInfo, 0); ULONG ulItems = DrgQueryDragitemCount (pDInfo); ULONG p; char **files; files = (char **)malloc( sizeof( char * ) * ulItems ); for (INT i=0; i < ulItems; i++) { CHAR DragSrcPath[CCHMAXPATH], DragSrcName[CCHMAXPATH]; pDItem = DrgQueryDragitemPtr(pDInfo, i); DrgQueryStrName(pDItem->hstrContainerName, sizeof(DragSrcPath), (PSZ)DragSrcPath); if (!(PSZ)DragSrcPath) break; if (DragSrcPath[(strlen(DragSrcPath)-1)] != '\\') strcat((PSZ)DragSrcPath, "\\"); /* Use the dragitem source name, it's the real name */ DrgQueryStrName(pDItem->hstrSourceName, sizeof(DragSrcName), (PSZ)DragSrcName); if (!((PSZ)DragSrcName)) break; strcat((PSZ)DragSrcPath, (PSZ)DragSrcName); FILESTATUS3 fsFile; DosError(FERR_DISABLEHARDERR); APIRET rc = DosQueryPathInfo(DragSrcPath, FIL_STANDARD, &fsFile, sizeof(FILESTATUS3)); DosError(FERR_ENABLEHARDERR); if (!rc && !(fsFile.attrFile & FILE_DIRECTORY)) { files[i] = (char *)malloc( strlen(DragSrcPath) + 1 ); strcpy( files[i], DragSrcPath ); DrgSendTransferMsg(pDItem->hwndItem, DM_ENDCONVERSATION, MPFROMLONG(pDItem->ulItemID), MPFROMLONG(DMFL_TARGETSUCCESSFUL)); } else { DosBeep(100,10); // EditorDisplay[BufNum]->DisplayMessage( pszDropNoFile ); } } filesDropped( files, ulItems ); for( i = 0; i < ulItems; i++ ) free( (void *)files[i] ); free( (void *)files ); DrgFreeDraginfo(pDInfo); break; } case WM_USER + 1 : { return (MPARAM)execFromMainThread( (int)mParam1, (void *)mParam2 ); } case WM_USER + 2 : { setFocus(); break; } } *returned = FALSE; return (MRESULT)NULL; }
static void AdjustControls(int NBPwidth, int NBPheight) { SWP swpTemp; int xsize, ysize; RECTL rectl; POINTL pointl; int buttonheight; ULONG CXDLGFRAME = WinQuerySysValue(HWND_DESKTOP, SV_CXDLGFRAME); ULONG CYDLGFRAME = WinQuerySysValue(HWND_DESKTOP, SV_CYDLGFRAME); // Query button height in pixels if (WinQueryWindowPos(WinWindowFromID(hwndConfigDlg, PB_DEFAULT), &swpTemp)) buttonheight = swpTemp.cy; else buttonheight = 0; // Set the size and position of Notebook // The size is interesting. We should know how much additional space this notebook requires. // For this, we calculate how big is a notebook for a known client size (e.g., 0x0) rectl.xLeft = 0; rectl.xRight = 0; rectl.yBottom = 0; rectl.yTop = 0; WinSendMsg(hwndConfigNB, BKM_CALCPAGERECT, MPFROMP(&rectl), MPFROMSHORT(FALSE)); // Ok, this must be added to client size in order to be able to display the given client dialog: NBPwidth += rectl.xRight; NBPheight += rectl.yTop; // Now check how much shift is inside the window: // (client/notebook shift) pointl.x = 0; pointl.y = 0; WinMapWindowPoints(hwndInterfaceNBP, hwndConfigNB, &pointl, 1); // Add this too: NBPwidth += pointl.x; NBPheight += pointl.y; // Notebook position is above the buttons, which is some pixels above the bottom of window: swpTemp.x = CXDLGFRAME+2; swpTemp.y = CYDLGFRAME + buttonheight + 5; // Notebook size is just calculated: swpTemp.cx = NBPwidth; swpTemp.cy = NBPheight; WinSetWindowPos(hwndConfigNB, HWND_TOP, swpTemp.x, swpTemp.y, swpTemp.cx, swpTemp.cy, SWP_MOVE | SWP_SIZE); // Ok, the notebook is resized. Now resize the dialog window to be just // as big as it's needed for the notebook: xsize = swpTemp.cx + CXDLGFRAME*2 + 2*2; ysize = swpTemp.cy + CYDLGFRAME*2 + buttonheight + 5 + WinQuerySysValue(HWND_DESKTOP, SV_CYTITLEBAR) + 5; WinSetWindowPos(hwndConfigDlg, HWND_TOP, 0, 0, xsize, ysize, SWP_SIZE); // Set the position of buttons // Undo Button WinQueryWindowPos(WinWindowFromID(hwndConfigDlg, PB_UNDO), &swpTemp); swpTemp.y = CYDLGFRAME+2; swpTemp.x = (xsize/6)*1-swpTemp.cx/2; WinSetWindowPos(WinWindowFromID(hwndConfigDlg, PB_UNDO), HWND_TOP, swpTemp.x, swpTemp.y, swpTemp.cx, swpTemp.cy, SWP_MOVE); // Default Button WinQueryWindowPos(WinWindowFromID(hwndConfigDlg, PB_DEFAULT), &swpTemp); swpTemp.y = CYDLGFRAME+2; swpTemp.x = (xsize/6)*3-swpTemp.cx/2; WinSetWindowPos(WinWindowFromID(hwndConfigDlg, PB_DEFAULT), HWND_TOP, swpTemp.x, swpTemp.y, swpTemp.cx, swpTemp.cy, SWP_MOVE); // Help Button WinQueryWindowPos(WinWindowFromID(hwndConfigDlg, PB_HELP), &swpTemp); swpTemp.y = CYDLGFRAME+2; swpTemp.x = (xsize/6)*5-swpTemp.cx/2; WinSetWindowPos(WinWindowFromID(hwndConfigDlg, PB_HELP), HWND_TOP, swpTemp.x, swpTemp.y, swpTemp.cx, swpTemp.cy, SWP_MOVE); // That's all! }
MRESULT EXPENTRY fnwpWxTaskWidget( HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2 ) { MRESULT mrc = 0; // get widget data from QWL_USER (stored there by WM_CREATE) PXCENTERWIDGET pWidget = (PXCENTERWIDGET)WinQueryWindowPtr( hwnd, QWL_USER ); // this ptr is valid after WM_CREATE switch( msg ) { /* * WM_CREATE: * as with all widgets, we receive a pointer to the * XCENTERWIDGET in mp1, which was created for us. * * The first thing the widget MUST do on WM_CREATE * is to store the XCENTERWIDGET pointer (from mp1) * in the QWL_USER window word by calling: * * WinSetWindowPtr(hwnd, QWL_USER, mp1); * * We could use XCENTERWIDGET.pUser for allocating * another private memory block for our own stuff, * for example to be able to store fonts and colors. * We ain't doing this in the minimal sample. */ case WM_CREATE: WinSetWindowPtr(hwnd, QWL_USER, mp1); pWidget = (PXCENTERWIDGET)mp1; if(( !pWidget ) || ( !pWidget->pfnwpDefWidgetProc )) { // shouldn't happen... stop window creation!! mrc = (MPARAM)TRUE; } hwndMenu = WinCreateWindow( hwnd, WC_MENU, 0, 0, 0, 0, 0, 0, hwnd, HWND_TOP, ID_MENU_TASKS, 0, 0 ); ico_tasks = WinLoadPointer( HWND_DESKTOP, hmodMe, ID_ICON_TASKS ); ico_detach = WinLoadPointer( HWND_DESKTOP, hmodMe, ID_ICON_DETACH ); ico_dos = WinLoadPointer( HWND_DESKTOP, hmodMe, ID_ICON_DOS ); ico_os2fs = WinLoadPointer( HWND_DESKTOP, hmodMe, ID_ICON_OS2FS ); ico_os2vio = WinLoadPointer( HWND_DESKTOP, hmodMe, ID_ICON_OS2VIO ); ico_pm = WinLoadPointer( HWND_DESKTOP, hmodMe, ID_ICON_PM ); break; /* * WM_BUTTON1CLICK: * clicked on the window */ case WM_BUTTON1CLICK: { mrc = (MPARAM)WgtControl( pWidget, mp1, mp2 ); RECTL rcl; POINTL ptl; SWP swp; // Check if Ctrl is pressed if( WinGetKeyState( HWND_DESKTOP, VK_CTRL ) & 0x8000 ) { bType = TRUE; } else { bType = FALSE; } // Fill it with items FillMenu( hwndMenu ); // Place popup according to xCenter position if( pWidget->pGlobals->ulPosition == XCENTER_BOTTOM ) { WinQueryWindowRect( hwnd, &rcl ); ptl.y = rcl.yTop + 1; ptl.x = rcl.xLeft; WinMapWindowPoints( HWND_DESKTOP, hwnd, &ptl, 0 ); } else { WinQueryWindowRect( hwnd, &rcl ); ptl.y = rcl.yBottom; ptl.x = rcl.xLeft; WinMapWindowPoints( HWND_DESKTOP, hwnd, &ptl, 0 ); memset( &swp, 0, sizeof(SWP)); swp.fl = SWP_SIZE; WinSendMsg( hwndMenu, WM_ADJUSTWINDOWPOS, MPFROMP(&swp), 0 ); ptl.y -= swp.cy; } // Show menu WinPopupMenu( hwnd, hwnd, hwndMenu, ptl.x, ptl.y, 0, PU_KEYBOARD | PU_MOUSEBUTTON1 | PU_HCONSTRAIN | PU_VCONSTRAIN ); break; } case WM_COMMAND: { char szPid[1024]; MENUITEM mi; SHORT id; TASKDATA* data; // Get menu id and data id = SHORT1FROMMP(mp1); WinSendMsg( hwndMenu, MM_QUERYITEM, MPFROM2SHORT( id, FALSE ), MPFROMP( &mi )); data = (TASKDATA*)mi.hItem; // Is it "our" item ?? if( id >= ID_ITEM_FIRST && id < 10000 ) { if( bType ) { // Ctrl was pressed on icon, kill pid if( WinGetKeyState( HWND_DESKTOP, VK_CTRL ) & 0x8000 ) { // Ctrl was pressed on menu item, use external kill sprintf( szPid, "Kill this process (%d) using fastio$ ?", data->pid ); if( WinMessageBox( HWND_DESKTOP, hwnd, szPid, "xCenter", 0, MB_ICONQUESTION | MB_YESNO | MB_APPLMODAL | MB_MOVEABLE | MB_DEFBUTTON2 ) == MBID_YES ) { DosKillFastIo( data->pid ); } } else { sprintf( szPid, "Are you sure that you want to kill this process (%d)?", data->pid ); if( WinMessageBox( HWND_DESKTOP, hwnd, szPid, "xCenter", 0, MB_ICONQUESTION | MB_YESNO | MB_APPLMODAL | MB_MOVEABLE | MB_DEFBUTTON2) == MBID_YES ) { DosKillProcess( DKP_PROCESS, data->pid ); } } } else { // No Ctrl, its a switch to task SwitchTo( data ); } } else { // Its Ulrichs menu, forward mrc = pWidget->pfnwpDefWidgetProc( hwnd, msg, mp1, mp2 ); } break; } /* * WM_CONTROL: * process notifications/queries from the XCenter. */ case WM_CONTROL: mrc = (MPARAM)WgtControl( pWidget, mp1, mp2 ); break; /* * WM_PAINT: * well, paint the widget. */ case WM_PAINT: WgtPaint( hwnd, pWidget ); break; /* * WM_PRESPARAMCHANGED: * A well-behaved widget would intercept * this and store fonts and colors. */ case WM_PRESPARAMCHANGED: break; case WM_MEASUREITEM: return MeasureMenuItem((POWNERITEM)mp2 ); case WM_DRAWITEM: return DrawMenuItem((POWNERITEM)mp2 ); /* * WM_DESTROY: * clean up. This _must_ be passed on to * ctrDefWidgetProc. */ case WM_DESTROY: // If we had any user data allocated in WM_CREATE // or elsewhere, we'd clean this up here. // We _MUST_ pass this on, or the default widget proc // cannot clean up. WinDestroyWindow ( hwndMenu ); WinDestroyPointer( ico_tasks ); WinDestroyPointer( ico_detach ); WinDestroyPointer( ico_dos ); WinDestroyPointer( ico_os2fs ); WinDestroyPointer( ico_os2vio ); WinDestroyPointer( ico_pm ); mrc = pWidget->pfnwpDefWidgetProc( hwnd, msg, mp1, mp2 ); break; default: mrc = pWidget->pfnwpDefWidgetProc( hwnd, msg, mp1, mp2 ); } return (mrc); }
void DoWaWEConfigureWindow(HWND hwndOwner) { SWP swpTemp, swpParent; POINTL ptlTemp; unsigned short usTabTextLength=0, usTabTextHeight=0; // The user wants to configure WaWE! // Save old config for Undo! memcpy(&WaWEUndoConfiguration, &WaWEConfiguration, sizeof(WaWEConfiguration)); // For this, we'll create a notebook window. // The first page of the notebook will contain the cache settings. // Later, it can have more notebook tabs, if required. #ifdef DEBUG_BUILD printf("[DoWaWEConfigureWindow] : Loading dialog from EXE...\n"); #endif hwndConfigDlg=WinLoadDlg(HWND_DESKTOP, hwndOwner, (PFNWP)ConfigDlgProc, NULL, DLG_CONFIGURATION, NULL); if (!hwndConfigDlg) { #ifdef DEBUG_BUILD printf("[DoWaWEConfigureWindow] : Could not load resource!\n"); #endif return; } #ifdef DEBUG_BUILD printf("[DoWaWEConfigureWindow] : Dialog loaded, others come...\n"); #endif // Query the handle of the notebook control hwndConfigNB = WinWindowFromID(hwndConfigDlg, NB_CONFIGURATION); // Now load and add the pages, one by one... hwndCacheNBP = WinLoadDlg(hwndConfigNB, hwndConfigNB, (PFNWP) fnCacheNotebookPage, NULL, DLG_CONFIGURATION_CACHE, NULL); hwndInterfaceNBP = WinLoadDlg(hwndConfigNB, hwndConfigNB, (PFNWP) fnInterfaceNotebookPage, NULL, DLG_CONFIGURATION_INTERFACE, NULL); // Save the size of one notebook page for later use. // (after adding, it will be resized, because of the AUDIOSIZE flag of notebook!) WinQueryWindowPos(hwndCacheNBP, &swpTemp); // Add pages to notebook: AddNotebookTab(hwndConfigNB, hwndInterfaceNBP, BKA_MAJOR, "Interface", "Interface settings", &(ulInterfaceNBPID), &usTabTextLength, &usTabTextHeight); AddNotebookTab(hwndConfigNB, hwndCacheNBP, BKA_MAJOR, "Cache", "Read-cache settings", &(ulCacheNBPID), &usTabTextLength, &usTabTextHeight); // The followings are discarder on Warp4, but makes things look better on Warp3: // Set notebook info field color (default is white... Yipe...) WinSendMsg(hwndConfigNB, BKM_SETNOTEBOOKCOLORS, MPFROMLONG(SYSCLR_FIELDBACKGROUND), MPFROMSHORT(BKA_BACKGROUNDPAGECOLORINDEX)); // Adjust tab size: WinSendMsg(hwndConfigNB, BKM_SETDIMENSIONS, MPFROM2SHORT(usTabTextLength + 10, (SHORT)((float)usTabTextHeight * 0.8)), MPFROMSHORT(BKA_MAJORTAB)); WinSendMsg(hwndConfigNB, BKM_SETDIMENSIONS, MPFROM2SHORT(0, 0), MPFROMSHORT(BKA_MINORTAB)); // Adjust controls and window size AdjustControls(swpTemp.cx, swpTemp.cy); // Position the window in the middle of its parent! WinQueryWindowPos(hwndOwner, &swpParent); ptlTemp.x = swpParent.x; ptlTemp.y = swpParent.y; WinMapWindowPoints(hwndOwner, HWND_DESKTOP, &ptlTemp, 1); swpParent.x = ptlTemp.x; swpParent.y = ptlTemp.y; WinQueryWindowPos(hwndConfigDlg, &swpTemp); swpTemp.x = (swpParent.cx-swpTemp.cx)/2 + swpParent.x; swpTemp.y = (swpParent.cy-swpTemp.cy)/2 + swpParent.y; WinSetWindowPos(hwndConfigDlg, HWND_TOP, swpTemp.x, swpTemp.y, 0, 0, SWP_MOVE); // Show window WinShowWindow(hwndConfigDlg, TRUE); WinSetFocus(HWND_DESKTOP, hwndConfigNB); #ifdef DEBUG_BUILD printf("[DoWaWEConfigureWindow] : Processing config window...\n"); #endif // Process messages WinProcessDlg(hwndConfigDlg); #ifdef DEBUG_BUILD printf("[DoWaWEConfigureWindow] : End of configuration!\n"); #endif // Now cleanup WinDestroyWindow(hwndConfigDlg); }
static MRESULT EXPENTRY launchPadWindowProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2) { WPFolder* thisPtr; launchPad * lp; LPObject *lpo; static USHORT id=0;//Initialisation new in V1.00a switch(msg) { #if 0 case DM_ENDCONVERSATION: case DM_DRAGFILECOMPLETE: case DM_DROPNOTIFY: case DM_FILERENDERED: case DM_RENDERCOMPLETE: break; return (MRESULT)FALSE; case WM_ENDDRAG: break; return (MRESULT)TRUE; #endif case WM_PAINT: { RECTL rcl; launchPad * lp; HPS hps=WinBeginPaint(hwnd,NULLHANDLE, &rcl); WinFillRect(hps, &rcl, SYSCLR_DIALOGBACKGROUND); lp=(launchPad*)WinQueryWindowULong(hwnd,QWL_USER); if(lp) { if(lp->lpQueryNumObjects()==0) { WinQueryWindowRect(hwnd,&rcl); WinDrawBorder(hps,&rcl,1,1,SYSCLR_WINDOWFRAME,SYSCLR_DIALOGBACKGROUND, DB_STANDARD); } } WinEndPaint(hps); return (MRESULT) 0; } case DM_DRAGOVER: return handleDragOver(hwnd, mp1, mp2); case DM_DROP: { ULONG ulCount; ULONG ulNumberOfObjects; PDRAGITEM pDragItem; SOMClass *folderClass; WPObject * wpObject; PDRAGINFO pDragInfo; TRY_LOUD(LP_FRAMEDROP) { /* A new object dropped on the launchpad */ pDragInfo=(PDRAGINFO)mp1; if(DrgAccessDraginfo(pDragInfo)) { /* Get number of items */ ulNumberOfObjects = DrgQueryDragitemCount( pDragInfo); if(ulNumberOfObjects>1){ /* Free the draginfo */ DrgDeleteDraginfoStrHandles(pDragInfo); DrgFreeDraginfo(pDragInfo); } else { ulCount=0; pDragItem=DrgQueryDragitemPtr( pDragInfo, ulCount); wpObject=(WPObject*)OBJECT_FROM_PREC(DrgQueryDragitemPtr( pDragInfo, ulCount)->ulItemID); lp=(launchPad*)WinQueryWindowULong(hwnd,QWL_USER); if(lp) { if(somIsObj(wpObject)) { POINTL ptl; int numB; SWP swp; WinQueryWindowPos(hwnd,&swp); ptl.x=pDragInfo->xDrop; ptl.y=pDragInfo->yDrop; /* Pos in window coords */ WinMapWindowPoints(HWND_DESKTOP, hwnd, &ptl, 1); numB=(ptl.x-xButtonOffset)/(swp.cy+xButtonDelta); numB=((ptl.x-numB*swp.cy) > swp.cy/2 ? numB+1: numB); /* Do a link */ lp->lpAddButton(wpObject, numB); handleDragLeave(hwnd, mp1, mp2); } } DrgDeleteDraginfoStrHandles(pDragInfo); DrgFreeDraginfo(pDragInfo); } } handleDragLeave(hwnd, mp1, mp2); } CATCH(LP_FRAMEDROP) { } END_CATCH; break; } case DM_DRAGLEAVE: return handleDragLeave(hwnd, mp1, mp2); break; case WM_COMMAND: if(SHORT1FROMMP(mp2)==CMDSRC_PUSHBUTTON) { /* It's a push button */ lpo=(LPObject*)WinQueryWindowULong(WinWindowFromID(hwnd,SHORT1FROMMP(mp1)),QWL_USER); if(lpo) { if(somIsObj(lpo->wpObject)) lpo->wpObject->wpViewObject(NULLHANDLE, OPEN_DEFAULT,0); } } return (MRESULT)FALSE; /***********************************************/ /* Stuff for fly over help */ case WM_MOUSEMOVE: launchPad * lp; lp=(launchPad*)WinQueryWindowULong(hwnd,QWL_USER); if(lp) { if(lp->lpQueryNumObjects()!=0) { break; } } #if 0 tempID=WinQueryWindowUShort(hwnd,QWS_ID);/* get the id of the window under the pointer */ if(id!=tempID) { // New Button? WinStartTimer(WinQueryAnchorBlock(hwnd),hwnd,tempID,(ULONG)iTBFlyOverDelay); // New timer for delay id=tempID; // Save ID } else { if(!hwndBubbleWindow) WinStartTimer(WinQueryAnchorBlock(hwnd),hwnd,tempID,(ULONG)iTBFlyOverDelay); // New timer for delay } #endif if(!hwndBubbleWindow) WinStartTimer(WinQueryAnchorBlock(hwnd), hwnd, 2,(ULONG)iTBFlyOverDelay); // New timer for delay break; case WM_DESTROY: WinStopTimer(WinQueryAnchorBlock(hwnd),hwnd,1);//Stop timer if running if(hwndBubbleWindow) WinDestroyWindow(hwndBubbleWindow);/* close the bubblewindow */ hwndBubbleWindow=0; /* Stop delay timer if running */ WinStopTimer(WinQueryAnchorBlock(hwnd),hwnd, 2); break; case WM_NEWBUBBLE: ULONG bubbleEnabled; HWND hwndStore; POINTL ptl; RECTL rclWork; LONG ulWinTextLen; POINTL aptlPoints[TXTBOX_COUNT]; LONG deltaX,deltaY; HPS hps; RECTL rcl; /* we have to build a new information window */ if(hwndBubbleWindow){// if(){...} new in V1.00a WinDestroyWindow(hwndBubbleWindow);/* close the bubblewindow */ hwndBubbleWindow=NULL; } // Query the pointer position WinQueryPointerPos(HWND_DESKTOP,&ptl); WinMapWindowPoints(HWND_DESKTOP,hwnd,&ptl,1); WinQueryWindowRect(hwnd,&rclWork); if(!hwndBubbleWindow && WinPtInRect(WinQueryAnchorBlock(hwnd),&rclWork,&ptl) && bTBFlyOverEnabled) { static HWND hwndBubbleClient; ULONG style=FCF_BORDER|FCF_NOBYTEALIGN; char winText[255]; /* Get window text for size calculating */ lp=(launchPad*)WinQueryWindowULong(hwnd,QWL_USER); if(lp) { strncpy(winText, lp->lpQueryFlyOverText(), sizeof(winText)); winText[sizeof(winText)-1]=0; } ulWinTextLen=(LONG)strlen(winText); // Query text length /* Delete 'Returns' in object title */ char *pBuchst; char *pRest; pRest=winText; while((pBuchst=strchr(pRest,13))!=NULL) { *pBuchst=' '; pBuchst++; if(*pBuchst==10) *pBuchst=' '; pRest=pBuchst; } /* Create help window */ hwndBubbleWindow=WinCreateStdWindow(HWND_DESKTOP, 0, &style, WC_STATIC, "", SS_TEXT|DT_CENTER|DT_VCENTER, NULLHANDLE, 400, &hwndBubbleClient); hwndShadow=WinCreateWindow(HWND_DESKTOP, WC_STATIC, "", SS_TEXT|DT_CENTER|DT_VCENTER, 0, 0, 0, 0, hwndBubbleWindow, hwndBubbleWindow, 401, NULLHANDLE, NULLHANDLE); oldProc=WinSubclassWindow(hwndShadow, shadowProc); // Set the font for the help WinSetPresParam(hwndBubbleClient,PP_FONTNAMESIZE, sizeof(chrTBFlyFontName), chrTBFlyFontName); /* Calculate text size in pixel */ hps=WinBeginPaint(hwndBubbleClient,(HPS)NULL,(PRECTL)NULL); GpiQueryTextBox(hps,ulWinTextLen,winText,TXTBOX_COUNT,aptlPoints); WinEndPaint(hps); /* Set colors */ WinSetPresParam(hwndBubbleClient, PP_BACKGROUNDCOLOR,sizeof(rgbTBFlyBackground) , &rgbTBFlyBackground ); WinSetPresParam(hwndBubbleClient, PP_FOREGROUNDCOLOR,sizeof(rgbTBFlyForeground) , &rgbTBFlyForeground ); /* Calculate bubble positon and show bubble */ WinQueryPointerPos(HWND_DESKTOP,&ptl);//Query pointer position in the desktop window WinQueryWindowRect(HWND_DESKTOP,&rcl);//Query desktop size aptlPoints[TXTBOX_BOTTOMRIGHT].x-aptlPoints[TXTBOX_BOTTOMLEFT].x+7+xVal+ptl.x > rcl.xRight ? deltaX=-aptlPoints[TXTBOX_BOTTOMRIGHT].x-aptlPoints[TXTBOX_BOTTOMLEFT].x-xVal-xVal-7 : deltaX=0 ; aptlPoints[TXTBOX_TOPLEFT].y-aptlPoints[TXTBOX_BOTTOMLEFT].y+2+yVal+ptl.y > rcl.yTop ? deltaY=-aptlPoints[TXTBOX_TOPLEFT].y-aptlPoints[TXTBOX_BOTTOMLEFT].y-2*yVal-7 : deltaY=0 ; WinSetWindowPos(hwndBubbleWindow, HWND_TOP, ptl.x+xVal+deltaX,ptl.y+yVal+deltaY, aptlPoints[TXTBOX_BOTTOMRIGHT].x-aptlPoints[TXTBOX_BOTTOMLEFT].x+8, aptlPoints[TXTBOX_TOPLEFT].y-aptlPoints[TXTBOX_BOTTOMLEFT].y+2, SWP_ZORDER|SWP_SIZE|SWP_MOVE|SWP_SHOW); WinSetWindowPos(hwndShadow, hwndBubbleWindow, ptl.x+xVal+deltaX+5 ,ptl.y+yVal+deltaY-5, aptlPoints[TXTBOX_BOTTOMRIGHT].x-aptlPoints[TXTBOX_BOTTOMLEFT].x+8, aptlPoints[TXTBOX_TOPLEFT].y-aptlPoints[TXTBOX_BOTTOMLEFT].y+2, SWP_ZORDER|SWP_SIZE|SWP_MOVE|SWP_SHOW); /* Set bubble text */ WinSetWindowText(hwndBubbleClient,winText); WinStartTimer(WinQueryAnchorBlock(hwnd),hwnd,1,35); } // end if(!hwndBubbleWindow) break; case WM_TIMER: switch (SHORT1FROMMP(mp1)) { case 1: //Intervall timer { POINTL ptl; RECTL rclWork; /* Test pointer position */ WinQueryPointerPos(HWND_DESKTOP, &ptl); WinMapWindowPoints(HWND_DESKTOP, hwnd,&ptl, 1); WinQueryWindowRect(hwnd, &rclWork); if(!WinPtInRect(WinQueryAnchorBlock(hwnd),&rclWork,&ptl)) { // Window has changed WinStopTimer(WinQueryAnchorBlock(hwnd), hwnd, 1); // stop the running timer if(hwndBubbleWindow) WinDestroyWindow(hwndBubbleWindow);/* close the bubblewindow */ hwndBubbleWindow=0; id=0; } break; } case 2:// delay over {//our own timer. POINTL ptl; RECTL rclWork; WinStopTimer(WinQueryAnchorBlock(hwnd), hwnd, 2);//Stop the delay timer /* Check the pointer position */ WinQueryPointerPos(HWND_DESKTOP,&ptl); WinMapWindowPoints(HWND_DESKTOP,hwnd,&ptl,1); WinQueryWindowRect(hwnd,&rclWork); if(WinPtInRect(WinQueryAnchorBlock(hwnd),&rclWork,&ptl)) WinPostMsg(hwnd,WM_NEWBUBBLE,NULL,NULL);//Request a help window return (MRESULT)FALSE; } default: break; } break; default: break; } return pfnwpOldLPProc(hwnd, msg, mp1, mp2); }
static VOID _calcViewRect(PGROPDATA pGrop, BOOL fSendSize) { PGROPSETMODE pUserMode = &pGrop->stUserMode; LONG lWinX, lWinY, lWinWidth, lWinHeight; LONG lVAWidth; LONG lVAHeight; if ( pGrop->ulModeIdx == ~0 ) // Mode was not selected. return; if ( pGrop->fFullscreen ) { PVIDEOMODE pMode = &pGrop->stModes.pList[pGrop->ulModeIdx]; lWinWidth = pMode->ulWidth; lWinHeight = pMode->ulHeight; lWinX = 0; lWinY = pGrop->ulDTHeight - lWinHeight; } else { SWP swp; POINTL pointl = { 0 }; WinQueryWindowPos( pGrop->hwnd, &swp ); lWinWidth = swp.cx; lWinHeight = swp.cy; WinMapWindowPoints( pGrop->hwnd, HWND_DESKTOP, &pointl, 1 ); lWinX = pointl.x; lWinY = pointl.y; } // Calc view rectangle size and position at center of window or screen if ( pGrop->pVideoSys->fFreeWinSize ) { // Fit output frame to window, keep proportional. if ( lWinWidth * pUserMode->ulHeight > lWinHeight * pUserMode->ulWidth ) { lVAHeight = lWinHeight; lVAWidth = ( lWinHeight * pUserMode->ulWidth ) / pUserMode->ulHeight; } else { lVAWidth = lWinWidth; lVAHeight = ( lWinWidth * pUserMode->ulHeight ) / pUserMode->ulWidth; } } else { lVAWidth = pUserMode->ulWidth; lVAHeight = pUserMode->ulHeight; } pGrop->rectlViewArea.xLeft = ( lWinWidth - lVAWidth ) / 2; pGrop->rectlViewArea.yBottom = ( lWinHeight - lVAHeight ) / 2; pGrop->rectlViewArea.xRight = pGrop->rectlViewArea.xLeft + lVAWidth; pGrop->rectlViewArea.yTop = pGrop->rectlViewArea.yBottom + lVAHeight; pGrop->rectlWinArea.xLeft = lWinX; pGrop->rectlWinArea.yBottom = lWinY; pGrop->rectlWinArea.xRight = lWinX + lWinWidth; pGrop->rectlWinArea.yTop = lWinY + lWinHeight; /* printf( "-1- %d %d %d %d - %d %d %d %d\n", pGrop->rectlViewArea.xLeft, pGrop->rectlViewArea.yBottom, pGrop->rectlViewArea.xRight, pGrop->rectlViewArea.yTop, pGrop->rectlWinArea.xLeft, pGrop->rectlWinArea.yBottom, pGrop->rectlWinArea.xRight, pGrop->rectlWinArea.yTop );*/ }