Demo's moving a window with a fake caption bar with a system menu.
And our ole' Pal resizable and movable control.
HTH
Regards, Jules
'========================{NCFUN.RC}===================='
[This message has been edited by Jules Marchildon (edited January 25, 2000).]
And our ole' Pal resizable and movable control.
HTH
Regards, Jules
Code:
'----------------------------------------------------------- ' NCFUN.BAS, Fool around with WM_NCHITEST to fake ' Sizable/Moveable Attributes. ' ' Let's convert ot PowerBasic PBDLL50 for Fun!!! ' By: Jules Marchildon, October 13, 1999 ' ' Help from Jim Huguley,Errol Cheivolle on C convertion and ' macro to sub convertion. '----------------------------------------------------------- $COMPILE EXE $INCLUDE "WIN32API.INC" $RESOURCE "NCFUN.PBR" '--- DECLARE SUB FigureHandleSizes(BYVAL hWnd AS LONG) DECLARE SUB ScreenToClientRect(BYVAL hWnd AS LONG, prRect AS RECT) '--- %IDM_MODAL = 100 %IDM_SYSMOVE = 101 'Fake Popup System Menu item %IDM_SYSCLOSE = 102 'Fake Popup System Menu item '--- GLOBAL ghInst AS LONG GLOBAL ghWnd AS LONG GLOBAL ghWndHalfHeight AS LONG GLOBAL ghWndButton AS LONG GLOBAL szAppName AS ASCIIZ*20 ' "NCFUN" GLOBAL szHalfHeightAppName AS ASCIIZ*20 ' "TinyTim" GLOBAL lpprocButton AS LONG GLOBAL lpprocButtonSubclass AS LONG GLOBAL hCaptionFont AS LONG GLOBAL hFakeSystemMenu AS LONG GLOBAL hFakeSystemPopupMenu AS LONG '--- TYPE GRIPPERS rcArea AS RECT 'Grippers coordinates dwNCHITVALUE AS DWORD 'NCHITTEST return value END TYPE '--- GLOBAL DialogHandles() AS GRIPPERS 'array of UDT Grippers '---------------------------------------------------------- FUNCTION WINMAIN(BYVAL hInstance AS LONG, _ BYVAL hPrevInstance AS LONG, _ lpszCmdLine AS ASCIIZ PTR, _ BYVAL nCmdShow AS LONG) AS LONG LOCAL Msg AS tagMsg LOCAL wc AS WNDCLASSEX IF ISFALSE(hPrevInstance) THEN '**Register Parent Window Class szAppName = "NCFUN" wc.cbSize = SIZEOF(wc) wc.style = %CS_HREDRAW OR %CS_VREDRAW OR %CS_BYTEALIGNCLIENT wc.lpfnWndProc = CODEPTR(WndProc) wc.cbClsExtra = 0 wc.cbWndExtra = 0 wc.hInstance = hInstance wc.hIcon = %NULL wc.hCursor = LoadCursor(%NULL, BYVAL %IDC_ARROW) wc.hbrBackground = GetStockObject(%WHITE_BRUSH) wc.lpszMenuName = %NULL wc.lpszClassName = VARPTR(szAppName) RegisterClassEx wc '--- '**Register the Half-Height Caption Child Window Class szHalfHeightAppName = "TinyTim" wc.cbSize = SIZEOF(wc) wc.style = %CS_BYTEALIGNCLIENT wc.lpfnWndProc = CODEPTR(HalfHeightWndProc) wc.cbClsExtra = 0 wc.cbWndExtra = 0 wc.hInstance = hInstance wc.hIcon = %NULL wc.hCursor = LoadCursor(%NULL, BYVAL %IDC_ARROW) wc.hbrBackground = GetStockObject(%WHITE_BRUSH) wc.lpszMenuName = %NULL wc.lpszClassName = VARPTR(szHalfHeightAppName) RegisterClassEx wc ELSE EXIT FUNCTION END IF '--- DIM DialogHandles(0:7) AS GRIPPERS '--- hCaptionFont = CreateFont ( -1*(GetSystemMetrics(%SM_CYCAPTION) \ 2), _ 0, 900, 900, 400, %FALSE, %FALSE, %FALSE, _ %ANSI_CHARSET, %OUT_CHARACTER_PRECIS, _ %CLIP_DEFAULT_PRECIS, %PROOF_QUALITY, _ %VARIABLE_PITCH OR %FF_SWISS, "Arial" ) ghInst = hInstance hFakeSystemPopupMenu = LoadMenu(ghInst,"FakeSysMenu") hFakeSystemMenu = GetSubMenu(hFakeSystemPopupMenu,0) '--- ghWnd = CreateWindow(szAppName, "Your ole' pal %WM_NCHITTEST", _ %WS_OVERLAPPEDWINDOW, _ GetSystemMetrics(%SM_CXSCREEN) \ 4, _ GetSystemMetrics(%SM_CYSCREEN) \ 4, _ GetSystemMetrics(%SM_CXSCREEN) \ 2, _ GetSystemMetrics(%SM_CYSCREEN) \ 2, _ %NULL, %NULL, hInstance, BYVAL %NULL) '--- ghWndHalfHeight = CreateWindow(szHalfHeightAppName, "Lets Get Small", _ %WS_POPUP OR %WS_VISIBLE OR %WS_THICKFRAME OR %WS_BORDER, _ 400, 200, _ 200, 200, _ ghWnd, %NULL, hInstance, BYVAL %NULL) '--- ghWndButton = CreateWindow("Button", "Move me now!", _ %WS_CHILD OR %WS_VISIBLE OR %WS_CLIPSIBLINGS OR %BS_PUSHBUTTON, _ 10, 10, _ 'OR %WS_BORDER 150, 50, _ ghWnd, %NULL, hInstance, BYVAL %NULL) '**SubClass the Button Control lpprocButton = SetWindowLong(ghWndButton,%GWL_WNDPROC, _ BYVAL CODEPTR(ControlSubClassProc)) ShowWindow ghWnd, %SW_SHOW UpdateWindow ghWnd '--- WHILE GetMessage(Msg, %NULL, 0, 0) TranslateMessage Msg DispatchMessage Msg WEND DeleteObject hCaptionFont DestroyMenu hFakeSystemPopupMenu FUNCTION = Msg.wParam END FUNCTION '------------------------------------------------------- FUNCTION WndProc(BYVAL hWnd AS LONG, _ BYVAL Msg AS LONG,BYVAL wParam AS LONG, _ BYVAL lParam AS LONG) AS LONG SELECT CASE Msg CASE %WM_DESTROY PostQuitMessage 0 'FUNCTION = 0 'EXIT FUNCTION CASE ELSE FUNCTION = DefWindowProc(hWnd,Msg,wParam,lParam ) EXIT FUNCTION END SELECT FUNCTION = 0 END FUNCTION '------------------------------------------------------ FUNCTION HalfHeightWndProc( BYVAL hWnd AS LONG, _ BYVAL Msg AS LONG, _ BYVAL wParam AS LONG, _ BYVAL lParam AS LONG) AS LONG LOCAL rc AS RECT LOCAL pt AS POINTAPI 'POINT LOCAL hDC AS LONG LOCAL ps AS PAINTSTRUCT LOCAL szCaption AS ASCIIZ*128 LOCAL iWidth AS LONG 'int LOCAL hOldFont AS LONG LOCAL hCaptionBrush AS LONG LOCAL wCaptionHeight AS LONG 'word SELECT CASE Msg CASE %WM_SIZE InvalidateRect hWnd,BYVAL %NULL,%FALSE 'FUNCTION = 0 'EXIT FUNCTION CASE %WM_ACTIVATE '**Force a repaint of the fake caption GetClientRect hWnd,rc rc.nright = rc.nleft + GetSystemMetrics(%SM_CYCAPTION )/2 InvalidateRect hWnd,rc,%FALSE 'FUNCTION =0 'EXIT FUNCTION CASE %WM_NCHITTEST GetClientRect hWnd,rc '**Figure the height of the fake caption rc.nright = rc.nleft + GetSystemMetrics(%SM_CYCAPTION)/2 '**remove out the area where the fake system menu is rc.ntop = GetSystemMetrics(%SM_CYCAPTION)/2 pt.x = LOWRD(lParam) pt.y = HIWRD(lParam) ScreenToClient hWnd,pt result& = PtInRect(rc, pt.x, pt.y) IF result& <> 0 THEN FUNCTION = %HTCAPTION 'EXIT FUNCTION ELSE FUNCTION = DefWindowProc(hWnd,msg,wParam,lParam) 'EXIT FUNCTION END IF EXIT FUNCTION '------- CASE %WM_LBUTTONDOWN IF ((LOWRD(lParam) < (GetSystemMetrics(%SM_CYCAPTION)/2)) _ AND (HIWRD(lParam) < (GetSystemMetrics(%SM_CYCAPTION)/2))) THEN pt.x = -1 pt.y = (GetSystemMetrics(%SM_CYCAPTION)/2)-1 ClientToScreen hWnd,pt TrackPopupMenu hFakeSystemMenu,0,pt.x,pt.y,0,hWnd,BYVAL %NULL END IF 'FUNCTION =0 'EXIT FUNCTION CASE %WM_PAINT wCaptionHeight = GetSystemMetrics(%SM_CYCAPTION)/2 hDC = BeginPaint(hWnd,ps) hOldFont = SelectObject(hDC,hCaptionFont) GetClientRect hWnd,rc rc.nright = wCaptionHeight rc.ntop = wCaptionHeight GetWindowText hWnd,szCaption,SIZEOF(szCaption) DIM sz AS SIZEL GetTextExtentPoint32 hDC,szCaption,LEN(szCaption),sz iWidth = sz.cx SetBkMode hDC, %NULL_BRUSH ' %TRANSPARENT IF GetFocus = hWnd THEN hCaptionBrush = CreateSolidBrush(GetSysColor(%COLOR_ACTIVECAPTION)) SetTextColor hDC,GetSysColor(%COLOR_CAPTIONTEXT) ELSE hCaptionBrush = CreateSolidBrush(GetSysColor(%COLOR_INACTIVECAPTION)) SetTextColor hDC,GetSysColor(%COLOR_INACTIVECAPTIONTEXT) END IF FillRect hDC,rc,hCaptionBrush DeleteObject hCaptionBrush ExtTextOut hDC, _ rc.nleft, _ rc.nbottom - (rc.nbottom-rc.ntop-iWidth)/2, _ %ETO_CLIPPED, _ rc, _ szCaption, _ LEN(szCaption), _ BYVAL %NULL SelectObject hDC,hOldFont '**Draw the fake close box rc.nright = wCaptionHeight rc.nleft = 0 rc.ntop = 0 rc.nbottom = wCaptionHeight SetBkColor hDC, RGB(192,192,192) SetBkColor hDC, RGB(255,0,0) ExtTextOut hDC, _ 0, _ 0,%ETO_OPAQUE OR %ETO_CLIPPED, _ rc, _ BYVAL %NULL, _ 0, _ BYVAL %NULL MoveToEx hDC,(rc.nright*1/5),(rc.nbottom/2),BYVAL %NULL LineTo hDC,(rc.nright*4/5),(rc.nbottom/2) EndPaint hWnd,ps 'FUNCTION = 0 'EXIT FUNCTION CASE %WM_COMMAND SELECT CASE wParam CASE %IDM_SYSMOVE SendMessage hWnd,%WM_SYSCOMMAND,%SC_MOVE,%NULL 'FUNCTION=0 'EXIT FUNCTION CASE %IDM_SYSCLOSE SendMessage hWnd,%WM_SYSCOMMAND,%SC_CLOSE,%NULL CASE ELSE FUNCTION = DefWindowProc(hWnd,Msg,wParam,lParam) EXIT FUNCTION END SELECT CASE ELSE FUNCTION = DefWindowProc(hWnd,Msg,wParam,lParam) EXIT FUNCTION END SELECT FUNCTION = 0 END FUNCTION '------------------------------------------------------------- FUNCTION ControlSubclassProc(BYVAL hWnd AS LONG, _ BYVAL Msg AS LONG,BYVAL wParam AS LONG, _ BYVAL lParam AS LONG) AS LONG LOCAL rc AS RECT LOCAL pt AS POINTAPI LOCAL hDC AS LONG LOCAL i AS LONG SELECT CASE Msg CASE %WM_NCHITTEST FigureHandleSizes hWnd GetClientRect hWnd,rc pt.x = LOWRD(lParam) pt.y = HIWRD(lParam) '**First, test for the "handles" FOR i = 0 TO 7 rc = DialogHandles(i).rcArea result& = PtInRect( rc, pt.x, pt.y ) IF result& <> 0 THEN FUNCTION = DialogHandles(i).dwNCHITVALUE EXIT FUNCTION END IF NEXT '--- '**Second, test for moving ScreenToClient hWnd,pt result& = PtInRect(rc, pt.x, pt.y) IF result& <> 0 THEN FUNCTION = CallWindowProc(lpprocButton,hWnd,Msg,wParam,lParam) 'EXIT FUNCTION ELSE FUNCTION = %HTCAPTION 'EXIT FUNCTION END IF CASE %WM_PAINT '**Let the control draw itself first CallWindowProc BYVAL lpprocButton, hWnd, Msg, wParam, lParam '**Draw Handles FigureHandleSizes hWnd hDC = GetWindowDC(hWnd) FOR i = 0 TO 7 rc = DialogHandles(i).rcArea ScreenToClientRect hWnd, rc FillRect hDC,rc,GetStockObject(%BLACK_BRUSH) NEXT ReleaseDC hWnd,hDC FUNCTION = 0 'EXIT FUNCTION CASE ELSE FUNCTION = CallWindowProc(BYVAL lpprocButton, hWnd, Msg, wParam, lParam) END SELECT END FUNCTION '--- SUB ScreenToClientRect(BYVAL hWnd AS LONG, prRect AS RECT) LOCAL pt AS POINTAPI pt.x = prRect.nleft pt.y = prRect.ntop ScreenToClient hWnd,pt prRect.nleft = pt.x prRect.ntop = pt.y pt.x = prRect.nright pt.y = prRect.nbottom ScreenToClient hWnd,pt prRect.nright = pt.x prRect.nbottom = pt.y END SUB '--- SUB FigureHandleSizes(BYVAL hWnd AS LONG) LOCAL rc AS RECT LOCAL dx AS LONG LOCAL dy AS LONG LOCAL x AS LONG LOCAL y AS LONG LOCAL dWHitValue AS DWORD LOCAL iIndex AS LONG '**Get the width and height of the window frame ' we want to put handles on. dx = GetSystemMetrics(%SM_CXFRAME) dy = GetSystemMetrics(%SM_CYFRAME)+1 'not sure why add 1 ??? CALL GetWindowRect(hWnd,rc) x = rc.nleft y = (rc.ntop + rc.nbottom) \ 2 - y \ 2 CALL MakeHandle(0, rc.nleft, (rc.ntop+rc.nbottom) \ 2 - dy \ 2, dx, dy,%HTLEFT) CALL MakeHandle(1, rc.nright-dx-1, (rc.ntop+rc.nbottom) \ 2-dy \ 2, dx, dy,%HTRIGHT) CALL MakeHandle(2, (rc.nleft+rc.nright) \ 2-dx \ 2, rc.ntop, dx, dy,%HTTOP) CALL MakeHandle(3, rc.nleft, rc.ntop, dx, dy,%HTTOPLEFT) CALL MakeHandle(4, rc.nright-dx-1, rc.ntop, dx, dy,%HTTOPRIGHT) CALL MakeHandle(5, (rc.nleft+rc.nright) \ 2-dx \ 2, rc.nbottom-dy-1, dx, dy,%HTBOTTOM) CALL MakeHandle(6, rc.nleft, rc.nbottom-dy-1, dx, dy,%HTBOTTOMLEFT) CALL MakeHandle(7, rc.nright-dy, rc.nbottom-dy-1, dx, dy,%HTBOTTOMRIGHT) END SUB '--- SUB MakeHandle(BYVAL iIndex AS LONG, _ BYVAL x AS LONG, _ BYVAL y AS LONG, _ BYVAL dx AS LONG, _ BYVAL dy AS LONG, _ BYVAL dwHitValue AS WORD) DialogHandles(iIndex).rcArea.nleft = x DialogHandles(iIndex).rcArea.ntop = y DialogHandles(iIndex).rcArea.nright = x+dx+1 'adjust size DialogHandles(iIndex).rcArea.nbottom = y+dy+1 'adjust size DialogHandles(iIndex).dwNCHITVALUE = dwHitValue END SUB
'========================{NCFUN.RC}===================='
Code:
#include "resource.h" // Menu ID's #define IDM_MODAL 100 #define IDM_SYSMOVE 101 #define IDM_SYSCLOSE 102 FakeSysMenu MENU BEGIN POPUP "Popup" BEGIN MENUITEM "&Move" , IDM_SYSMOVE MENUITEM "&Close", IDM_SYSCLOSE END END
Comment