******************************************************************************** * Program : BMDLGRES.PRG * Launch BMDLGRES.EXE * Aim : Show how to program Applications using Windows traditional manner, * ..........: with NTKCORE GUI (low level) set of functions for X/HARBOUR. * ..........: This sample illustrate GDI drawing possibilities of NTKCORE : * ..........: Memory Bitmap manipulation using Dialog event-driven interface * Make......: Juste type MK BMDLGRES * Date : 17/05/06 * Author(s) : Jn DECHEREUX * Copyright : (c) 2006 - Jn DECHEREUX. Tous droits r‚serv‚s/All Rights Reserved. ******************************************************************************** * Remark: * I have to confess that English is not mother tongue. So, in case of * typo or misspelling, don't be too angry - just bear with me. * You have to know that i'll do consider any comment, correction, suggestion * with great pleasure and high kindliness. Just be polite ! ;-) * This remark is also available for bug notifications or any other kind of * contributions that can improve my product... ******************************************************************************** * * For further explanations about GDI drawing purpose, feel free to consult MSDN * documentation website at : * http://msdn.microsoft.com/library/default.asp * * As, explanations about the advanced drawing techniques used in this sample are * beyond the scope of NTKCORE's manual, do not hesitate to dive in Petzold's book... * ********************************************************************************** #define ISOLATION_AWARE_ENABLED 1 // Harbour includes #include "cstruct.ch" // NTK includes #include "wintypes.ch" #include "windows.ch" #include "NTKIMG.CH" #include "ntkgdi.ch" #include "ntkmsg.ch" #include "ntkacc.ch" #include "ntkcctrl.ch" #include "ntkttips.ch" #include "wNtk.ch" #define CR CHR(13) #define CRLF CHR(13)+CHR(10) #define TAB CHR(9) #include "bmdlgres.ch" FUNCTION MAIN() LOCAL cMsg LOCAL NTK_aMSG := { 0,0,0,0,0,0,0 } // 7 elements, see NTKMSG.CH LOCAL hInst := NTK_GetInstance() LOCAL hIcon := NTK_LoadIcon( Nil , IDI_HAND ) // IDI_APPLICATION) LOCAL hCurs := NTK_LoadCursor( Nil , IDC_ARROW) LOCAL hBrush := NTK_GetStockObject(WHITE_BRUSH) //LTGRAY_BRUSH) LOCAL cWinTitle := "Example of BMDLGRES control with NTKCore for X/HRB !" LOCAL hWndMain PRIVATE aDemoFont1 PRIVATE hDemoFont1 PRIVATE hMyBmp := NTK_ReadPictureToBmp( "Tux.bmp" ) // ----- Ensure that the common control dynamic-link library (DLL) is loaded. // ----- Don't forget to use this command if U plan to use controls such as DatePicker, BMDLGRESs... NTK_InitCommonControlsEx( ICC_DATE_CLASSES + ICC_BAR_CLASSES + ICC_STANDARD_CLASSES + ICC_WIN95_CLASSES ) IF !NTK_RegisterClassEx( CS_HREDRAW + CS_VREDRAW,; // CS_OWNDC + CS_VREDRAW + CS_HREDRAW + CS_DBLCLKS,; hInst,; hIcon,; hCurs,; hBrush,; "NTKFEN",; { |hWnd, message, nwParam, nlParam|; MAINWNDPROC(hWnd, message, nwParam, nlParam) } ) NTK_MsgBox( , "Can't register NTKFEN class..." ) RETURN Nil ENDIF hWndMain = NTK_CreateWindowEx( WS_EX_WINDOWEDGE, "NTKFEN", cWinTitle, ; F_MAX+ WS_OVERLAPPED + WS_CAPTION + WS_THICKFRAME +WS_SYSMENU,; 0, 0, CW_USEDEFAULT, CW_USEDEFAULT ) IF hWndMain == 0 NTK_MsgBox( , "Can not create MAIN Window..." ) RETURN Nil ENDIF * we want want an invisible main window... so don't show it! *NTK_ShowWindow( hWndMain, SW_NORMAL ) *NTK_UpdateWindow( hWndMain ) nResDlg := NTK_DialogBox( hInst, "BMMAINDLG", ,; {|hDlg, msg, wparam, lparam| ; ResDlgProc(hDlg, msg, wparam, lparam)} ) NTK_MsgBox( , STR(nResDlg), "DialogBox() result :" ) NTK_DeleteObject( hMyBmp ) NTK_UnregisterClass( "NTKFEN", hInst ) RETURN ****** ****** ****** FUNCTION MAINWNDPROC( hWnd, message, nwParam, nlParam) RETURN( NTK_DEFWNDPROC(hWnd, message, nwParam, nlParam) ) ****** ****** // Resource Dialog WndProc FUNCTION ResDlgProc(hWndDlg, nMsg, nwParam, nlParam) LOCAL aPS := { 0,.T.,0,0,0,0,.T.,.T.,nil } // 9 elements, see NTKGDI.CH LOCAL hDC := 0 LOCAL aRcBmp, nBmDstWidth, nBmDstHeight, aRcDlg // Message from Windows : // - hWndDlg Handle to the Dialog // - nMsg Message number // - nwParam ID of the control (child window ) // - nlParam handle to the child window + notification code DO CASE CASE nmsg == WM_INITDIALOG // DLG INITIALIZATION // Windows sends this message as soon as the Dlg is created. // Unlike a classic window procedure a Dialog doesn't send // WM_CREATE msg, but WM_INITDIALOG... RETURN .F. CASE nmsg == WM_COMMAND // Windows sends this message as soon as you click on a control (EDIT,BUTTON,LISTBOX, ...) // nwparam is the control ID Do Case Case nwparam==IDCANCEL // 2 - 'Cancel' Button // Tell Windows to close the Dialog //NTK_DestroyWindow(hWndDlg, nwparam) NTK_EndDialog(hWndDlg, nwparam) RETURN .T. * Case nwparam==IDOK // 1 - 'Save' Button * * // Tell Windows to close the Dialog * NTK_EndDialog(hWndDlg, nwparam) * RETURN .T. Case nwparam==IDC_OPEN // 'Open' Button IF DoOpenFileDlg(hWndDlg) NTK_InvalidateRect(hWndDlg) ENDIF RETURN .T. Case nwparam==IDC_ADAPT // 'Adapt' Button //aRcSrc := {30, 0, 70, 40} aRcBmp := NTK_GetBmpRect(hMyBmp) aRcDlg := NTK_GetClientRect(hWndDlg) nBmDstWidth := aRcDlg[RECT_Width] nBmDstHeight := aRcDlg[RECT_Height] hDc := NTK_GetDC(hWndDlg) hMyBmp := DoResizeBmp( hDc, hMyBmp, aRcBmp, nBmDstWidth, nBmDstHeight ) NTK_ReleaseDC(hWndDlg, hDc) NTK_InvalidateRect(hWndDlg) RETURN .T. EndCase CASE nmsg == WM_PAINT hDC := NTK_BeginPaint( hWndDlg, aPS ) IF !EMPTY(hMyBmp) //NTK_DrawBmp( hDC, hMyBmp, 158, 76, SRCCOPY ) // Win XP NTK_DrawBmp( hDC, hMyBmp, 0, 0, SRCCOPY ) // Win XP ENDIF NTK_EndPaint( hWndDlg, aPS ) ENDCASE RETURN .F. ****** ****** ****** ****** ****************************************************************************************** FUNCTION DoOpenFileDlg(hWnd) LOCAL cFile LOCAL aFilter := { { "Images", "*.bmp;*.gif;*.jpg" } } LOCAL MyPictFolder cFile := NTK_GetOpenFileName( hWnd, "*.bmp;*.gif;*.jpg", "Pick a image file...", aFilter, , MyPictFolder ) IF cFile == Nil //NTK_MsgBox( hWnd, "Nothing and cancel", "You chose to open:", MB_OK+MB_ICONASTERISK ) RETURN .F. ENDIF IF hMyBmp != Nil NTK_DeleteObject( hMyBmp ) ENDIF hMyBmp := NTK_ReadPictureToBmp( cFile ) RETURN .T. ****** ****** ****** Function DoResizeBmp( hDc, hBmpSrc, aRcSrc, nBmDstWidth, nBmDstHeight ) Local hBmpDst, aSizeSrc LOCAL hOldBmpSrc, hOldBmpDst nBmDstWidth := IIF( nBmDstWidth == NIL, 0, nBmDstWidth ) nBmDstHeight := IIF( nBmDstHeight== NIL, 0, nBmDstHeight ) aRcSrc := IIF( aRcSrc==NIL, {0,0,0,0}, aRcSrc ) // # HBITMAP RedimBmp(HDC hdc, HBITMAP hBmpSrc, RECT rcSrc, SIZE sizeDst) // taille du bitmap initial / orignal bitmap size aSizeSrc = NTK_GetBmpRect(hBmpSrc); // si aRcSrc est … {0,0,0,0}, on prend toute l'image source // if aRcSrc is set to {0,0,0,0}, take the whole source picture IF( aRcSrc[RECT_Left]==0 .AND. aRcSrc[RECT_Top]==0 .AND. aRcSrc[RECT_Right]==0 .AND. aRcSrc[RECT_Bottom]==0 ) aRcSrc[RECT_Right] := aSizeSrc[RECT_Right] aRcSrc[RECT_Bottom] := aSizeSrc[RECT_Bottom] ENDIF // v‚rification des bornes / check for limits IF(aRcSrc[RECT_Left] < 0) aRcSrc[RECT_Left] := 0 ENDIF IF(aRcSrc[RECT_Top] < 0) aRcSrc[RECT_Top] := 0 ENDIF IF(aRcSrc[RECT_Right] > aSizeSrc[RECT_Right]) aRcSrc[RECT_Right] := aSizeSrc[RECT_Right] ENDIF IF(aRcSrc[RECT_Bottom] > aSizeSrc[RECT_Bottom]) aRcSrc[RECT_Bottom] := aSizeSrc[RECT_Bottom] ENDIF // si sizeDst est … {0,0}, on ne fait pas de redimensionnement // We don't resize anything when nBmDstWidth==0 nBmDstHeight==0 IF(nBmDstWidth==0 .AND. nBmDstHeight==0) nBmDstWidth := aRcSrc[RECT_Right] - aRcSrc[RECT_Left] nBmDstHeight := aRcSrc[RECT_Bottom] - aRcSrc[RECT_Top] ENDIF //cr‚ation de DCs compatibles et du bitmap de destination // Creates comptatible DC and destination Bitmap hDCSrc := NTK_CreateCompatibleDC(hDc) hDCDst := NTK_CreateCompatibleDC(hDc) hBmpDst := NTK_CreateCompatibleBitmap(hDc, nBmDstWidth, nBmDstHeight) // s‚lection des bitmaps dans les DCs (avec sauvegarde des anciens) // Stores bitmaps into DCs (and save old ones) hOldBmpSrc := NTK_SelectObject(hDCSrc, hBmpSrc) hOldBmpDst := NTK_SelectObject(hDCDst, hBmpDst) // recopie / copy NTK_SetStretchBltMode(hDCDst, HALFTONE) NTK_StretchBlt(hDCDst, 0, 0, nBmDstWidth, nBmDstHeight, hDCSrc,; aRcSrc[RECT_Left], aRcSrc[RECT_Top],; (aRcSrc[RECT_Right]-aRcSrc[RECT_Left]), (aRcSrc[RECT_Bottom]-aRcSrc[RECT_Top]),; SRCCOPY) // s‚lection des anciens bitmaps dans les DCS // Destroy old bitmaps & DCs NTK_SelectObject(hDCSrc, hOldBmpSrc) NTK_SelectObject(hDCDst, hOldBmpDst) // destruction des DCs // Destroy current DCs NTK_DeleteDC(hDCSrc) NTK_DeleteDC(hDCDst) RETURN( hBmpDst ) ****** ****** ******