****************************************************************************** * Program : MDIDEMO.PRG * Launch MDIDEMO.EXE * ..........: Another MDI 'Hello World' demonstration using NTK RAD * Make : MKRAD MDIDEMO * Date : 19/09/08 * Author(s) : Jn DECHEREUX * Copyright : (c) 2008 - Jn DECHEREUX. Tous droits réservés/All Rights Reserved. ******************************************************************************** #include "windows.ch" #include "ntkgdi.ch" #include "ntkmsg.ch" #include "ntkacc.ch" #include "ntkcmd.ch" #include "ntkcmdEx.ch" #include "ntkmdi.ch" #include "wNtk.ch" #include "wNtkKeys.ch" #include "mdieasy.ch" #define CR CHR(13) #define REQUEST_NONE 0 #define REQUEST_MDITILE 1 #define REQUEST_MDIMOVE 2 STATIC hWndFrame STATIC hWndMDIClient STATIC aMDIChild STATIC hLogoNtk, hLogoBmp FUNCTION MAIN() LOCAL cFrameTitle := "Yet another MDI demonstrationn using NTKrad system..." PRIVATE nMDIClientFlag := REQUEST_NONE aMDIChild := {} hLogoNtk := NTK_ReadPictureToBmp( "./pict/Ntk.jpg" ) hLogoBmp := NTK_ReadPictureToBmp( "./pict/DbEdit128.bmp" ) // First, we create the MDI Frame window CREATE WINDOW hWndFrame RCF_MDIFRAME MENU "MyMenu" TITLE cFrameTitle ; ICON NTK_LoadIcon( NTK_GetInstance() , "ID_MDIFRAME" ) ; ON PAINT DoFramePaint() ; ON MSG DoFrameEvent() ; ON EXIT DoFrameExit() // As each frame has got its buddy MDI Client window, we ask for it! hWndMDIClient := __NTKGetMDIClient(hWndFrame) // just keep in mind we'll need it later... ACTIVATE WINDOW hWndFrame NORMAL // Display the current window and its child controls // Second, as the the frame is now active, we can create MDI Child window(s) inside... NewMDIChild(0,0, 500,200 ) // At least, we want one MDI child window at startup. AUTO HANDLE EVENTS OF WINDOW hWndFrame // Start processing background events (animate the frame window) NTK_DeleteObject( hLogoBmp ) NTK_DeleteObject( hLogoNtk ) CLOSE WINDOW hWndFrame CLOSE DATABASES RETURN ****** ****** ****** **FUNCTION DoExit() ** //NTK_PostQuitMessage(0) // tell OS to terminate the main application. Do not forget! ** NTK_SendQuitEvent() // Same as NTK_PostQuitMessage(0), but also return .T. autmatically. see below... **RETURN(.T. ) // .T. tell NTK RAD system to terminate handling events for this window FUNCTION DoFrameExit(hWnd,Msg,wParam,lParam) IF NTK_MsgBox( hWnd,; "Do you really want to quit the application ?",; "Your Attention Please !",; MB_OKCANCEL+MB_ICONQUESTION+MB_TOPMOST ) == IDOK NTK_PostQuitMessage(0) RETURN(.T.) // Quit ENDIF RETURN(.F.) // Do not quit, keep on current task ****** ****** ****** ****** ****** ****** FUNCTION DoFramePaint(hWnd, message, nwParam, nlParam, hDC) Local nScreenH := __NtkMaxRow(hWnd) Local nScreenW := __NtkMaxCol(hWnd) Local aLogoSize := NTK_GetBmpRect( hLogoBmp ) Local nLogoX := (nScreenW/2)-(aLogoSize[RECT_Width]/2) Local nLogoY := (nScreenH/2)-(aLogoSize[RECT_Height]/2) Local aNtksize := NTK_GetBmpRect( hLogoNtk ) Local nNtkX := nScreenW - aNtkSize[RECT_Width] @ 00,00 SAY WALLPAPER ID ID_FRAMEBKG TO hWnd INTO CONTEXT hDC // Main frame Bkg SET COLOR TO R+/W+ @ 080,100 SAY "Hello World from the MDI FRAME window !" INTO CONTEXT hDC @ 00, nNtkX SAY BITMAP hLogoNtk INTO CONTEXT hDC @ nLogoY, nLogoX SAY BITMAP hLogoBmp ; TRANSPARENCY BY NTK_RGB(255 ,000 ,255) ; //Magenta INTO CONTEXT hDC RETURN(0) ****** ****** ****** FUNCTION DoFrameEvent(hWnd, message, nwParam, nlParam) IF message==WM_COMMAND // we process only Menu messages DO CASE CASE nwParam == IDM_FILENEW // Make an empty MDI child window NewMDIChild() RETURN(0) CASE nwParam == IDM_FILEEXIT NTK_SendMessage(hWnd, WM_CLOSE, 0, 0) // close down RETURN(0) CASE nwParam == IDM_WINDOWTILE NTK_SendMessage(hWndMDIClient, WM_MDITILE, 0, 0) FOR nChildPos := 1 TO LEN(aMDIChild) FitBrowseInWindow( aMDIChild[nChildPos, 1] ) NEXT nMDIClientFlag := REQUEST_MDITILE RETURN(0) CASE nwParam == IDM_WINDOWCASCADE NTK_SendMessage(hWndMDIClient, WM_MDICASCADE, 0, 0) RETURN(0) CASE nwParam == IDM_WINDOWICONS // auto-arrange icons NTK_SendMessage(hWndMDIClient, WM_MDIICONARRANGE, 0, 0) RETURN(0) CASE nwParam == IDM_WINDOWCLOSEALL CloseAllChildren() RETURN(0) ENDCASE ENDIF RETURN( NTK_DefFrameProc(hWnd, hWndMDIClient, message, nwParam, nlParam ) ) ****** ****** ****** STATIC FUNCTION NewMDIChild(nX,nY,nW,nH) Local hWndMDIChild Local cNewAlias Local oB CREATE WINDOW hWndChild RCF_MDICHILD ; CHILD OF hWndMDIClient ; AT nX, nY SIZE nW,nH ; ICON NTK_LoadIcon( NTK_GetInstance() , "ID_MDICHILD" ) ; TITLE "Child #" + AllTrim( STR(Len(aMDIChild)+1) ) ; ON PAINT DoChildPaint() ; ON MSG DoChildEvent() ; ON EXIT DoChildExit() IF hWndChild==0 NTK_MsgBox(nil, "Cannot create MDI Child window in this frame...", "Alert!", MB_ICONEXCLAMATION+MB_TOPMOST ) RETURN(0) ENDIF // ------ Databases opening and creation of new DbGrid child object inside the MDI child parent... cNewAlias := "DB"+STRZERO( Len(aMDIChild)+1, 10 ) USE ("PRODUCT.DBF") SHARE ALIAS (cNewAlias) NEW @ 000,000 TO __NtkMaxRow(hWndChild),__NtkMaxCol(hWndChild) ; CREATE BROWSE oB ; WITH DBAREA (cNewAlias) ; // This can also be used: WITH DBAREA 1; FIELDS Codeart, Codebarre, Designart, PuaHT, PuvHT ; // Optional: Needed Field list... INTO hWndChild //STYLE WS_CHILD+WS_VISIBLE+WS_OVERLAPPED+WS_THICKFRAME; // Use this if you allow user the ability to resize browse control... oB:Configure() // ------------------------------------------------------------------------------------------------------------- AADD( aMDIChild, { hWndChild, oB } ) // Keep trace of each created MDI Child window ACTIVATE WINDOW hWndChild NORMAL // Display the current window and its child controls NTK_SetFocus(oB:hWnd) RETURN(hWndChild) ****** ****** ****** FUNCTION DoChildExit(hWnd,Msg,wParam,lParam) IF NTK_MsgBox( hWnd,; "Do you really want to exit this child window ?",; "Alert from "+NTK_GetWindowText(hWnd),; MB_OKCANCEL+MB_ICONQUESTION+MB_TOPMOST ) == IDOK RETURN(.T.) // exit from child window ENDIF RETURN(.F.) // Do not quit, keep on current task ****** ****** ****** ****** FUNCTION DoChildPaint(hWnd, message, nwParam, nlParam, hDC) //LOCAL nChildPos := ASCAN( aMDIChild, { |aVal| aVal[1]==hWnd } ) //SET COLOR TO B+/N+ //@ 080,100 SAY "Hello World from the MDI Child window #" + AllTrim( STR(nChildPos) ) INTO CONTEXT hDC RETURN(0) ****** ****** ****** FUNCTION DoChildEvent(hWnd, message, nwParam, nlParam) Local nChildPos Local oB // The following code is used to resize/adpat the browse/datagrid object // consequently to specific events occuring in its MDIChild parent... DO CASE CASE message == WM_SIZE // adjust the child dataGrid/Browse control to the MDI child window FitBrowseInWindow( hWnd, .T. ) CASE message == WM_SYSCOMMAND If nwParam==SC_MAXIMIZE .OR. nwParam==SC_MINIMIZE // adjust the child dataGrid/Browse control to the MDI child window FitBrowseInWindow( hWnd ) EndIf CASE message == WM_MOVE nMDIClientFlag := REQUEST_MDIMOVE CASE message == WM_EXITSIZEMOVE IF nMDIClientFlag == REQUEST_MDIMOVE nMDIClientFlag := REQUEST_NONE ELSE nChildPos := ASCAN( aMDIChild, { |aVal| aVal[1]==hWnd } ) If nChildPos > 0 oB := aMDIChild[ nChildPos, 2 ] NTK_PostMessage( oB:hWnd, WM_EXITSIZEMOVE, 0, 0 ) EndIf nMDIClientFlag := REQUEST_NONE ENDIF ENDCASE RETURN( NTK_DefMDIChildProc(hWnd, message, nwParam, nlParam) ) ****** ****** ****** STATIC PROCEDURE CloseAllChildren() local hWnd // find and destroy the MDI children DO WHILE (hWnd := NTK_GetWindow(hWndMDIClient, GW_CHILD)) != 0 // skip the icon title windows Do While hWnd != 0 .and. NTK_GetWindow(hWnd, GW_OWNER) != 0 hWnd = NTK_GetWindow(hWnd, GW_HWNDNEXT) EndDo IF hWnd == 0 EXIT ENDIF NTK_SendMessage(hWndMDIClient, WM_MDIDESTROY, hWnd, 0) ENDDO CLOSE DATABASES RETURN ****** ****** STATIC FUNCTION FitBrowseInWindow( hWndP, lResize ) Local oB Local nChildPos Default hWndP To NTK_SelectWindow() Default lResize To .F. nChildPos := ASCAN( aMDIChild, { |aVal| aVal[1]==hWndP } ) If nChildPos > 0 oB := aMDIChild[ nChildPos, 2 ] NTK_MoveWindow(oB:hWnd,; oB:nubWidth,; 0,; __NTKMaxCol(hWndP)-oB:nubWidth,; __NTKMaxRow(hWndP),; .T.) if !lResize NTK_PostMessage( oB:hWnd, WM_EXITSIZEMOVE, 0, 0 ) endif EndIf RETURN( Nil ) ****** ****** ******