/* * Default window procedure * * Copyright 1993 Alexandre Julliard * 1995 Alex Korobka */ #include #include #include "win.h" #include "class.h" #include "user.h" #include "nonclient.h" #include "winpos.h" #include "syscolor.h" #include "stddebug.h" /* #define DEBUG_MESSAGE */ #include "debug.h" #include "spy.h" /* Last COLOR id */ #define COLOR_MAX COLOR_BTNHIGHLIGHT /* bits in the dwKeyData */ #define KEYDATA_ALT 0x2000 #define KEYDATA_PREVSTATE 0x4000 static short iF10Key = 0; static short iMenuSysKey = 0; /*********************************************************************** * DEFWND_SetText * * Set the window text. */ void DEFWND_SetText( HWND hwnd, LPSTR text ) { LPSTR textPtr; WND *wndPtr = WIN_FindWndPtr( hwnd ); if (!text) text = ""; if (wndPtr->hText) USER_HEAP_FREE( wndPtr->hText ); wndPtr->hText = USER_HEAP_ALLOC( strlen(text) + 1 ); textPtr = (LPSTR) USER_HEAP_LIN_ADDR( wndPtr->hText ); strcpy( textPtr, text ); if (wndPtr->window) XStoreName( display, wndPtr->window, text ); } /*********************************************************************** * DefWindowProc (USER.107) */ LRESULT DefWindowProc( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam ) { CLASS * classPtr; LPSTR textPtr; int len; WND * wndPtr = WIN_FindWndPtr( hwnd ); SPY_EnterMessage( SPY_DEFWNDPROC, hwnd, msg, wParam, lParam ); switch(msg) { case WM_NCCREATE: { CREATESTRUCT *createStruct = (CREATESTRUCT*)PTR_SEG_TO_LIN(lParam); if (createStruct->lpszName) DEFWND_SetText( hwnd, (LPSTR)PTR_SEG_TO_LIN(createStruct->lpszName) ); return 1; } case WM_NCCALCSIZE: return NC_HandleNCCalcSize( hwnd, (NCCALCSIZE_PARAMS *)PTR_SEG_TO_LIN(lParam) ); case WM_PAINTICON: case WM_NCPAINT: return NC_HandleNCPaint( hwnd, (HRGN)wParam ); case WM_NCHITTEST: { POINT pt = { LOWORD(lParam), HIWORD(lParam) }; return NC_HandleNCHitTest( hwnd, pt ); } case WM_NCLBUTTONDOWN: return NC_HandleNCLButtonDown( hwnd, wParam, lParam ); case WM_LBUTTONDBLCLK: case WM_NCLBUTTONDBLCLK: return NC_HandleNCLButtonDblClk( hwnd, wParam, lParam ); case WM_NCACTIVATE: return NC_HandleNCActivate( hwnd, wParam ); case WM_NCDESTROY: if (wndPtr->hText) USER_HEAP_FREE(wndPtr->hText); if (wndPtr->hVScroll) USER_HEAP_FREE(wndPtr->hVScroll); if (wndPtr->hHScroll) USER_HEAP_FREE(wndPtr->hHScroll); wndPtr->hText = wndPtr->hVScroll = wndPtr->hHScroll = 0; return 0; case WM_PAINT: { PAINTSTRUCT paintstruct; BeginPaint( hwnd, &paintstruct ); EndPaint( hwnd, &paintstruct ); return 0; } case WM_SETREDRAW: if (!wParam) { ValidateRect( hwnd, NULL ); wndPtr->flags |= WIN_NO_REDRAW; } else wndPtr->flags &= ~WIN_NO_REDRAW; return 0; case WM_CLOSE: DestroyWindow( hwnd ); return 0; case WM_MOUSEACTIVATE: if (wndPtr->dwStyle & WS_CHILD) { LONG ret = SendMessage( wndPtr->parent->hwndSelf, WM_MOUSEACTIVATE, wParam, lParam ); if (ret) return ret; } return MA_ACTIVATE; case WM_ACTIVATE: /* LOWORD() needed for WINELIB32 implementation. Should be fine. */ if (LOWORD(wParam)!=WA_INACTIVE) SetFocus( hwnd ); break; case WM_WINDOWPOSCHANGING: return WINPOS_HandleWindowPosChanging( (WINDOWPOS *)PTR_SEG_TO_LIN(lParam) ); case WM_WINDOWPOSCHANGED: { /* Note: Windoze uses unknown SWP flags 0x1000 and 0x0800 to * decide whether to send WM_MOVE or/and WM_SIZE respectively */ WINDOWPOS * winPos = (WINDOWPOS *)PTR_SEG_TO_LIN(lParam); WPARAM wp = SIZE_RESTORED; if (!(winPos->flags & SWP_NOMOVE)) SendMessage( hwnd, WM_MOVE, 0, MAKELONG( wndPtr->rectClient.left, wndPtr->rectClient.top )); if (!(winPos->flags & SWP_NOSIZE)) { if( wndPtr->dwStyle & WS_MAXIMIZE ) wp = SIZE_MAXIMIZED; else if(wndPtr->dwStyle & WS_MINIMIZE ) wp = SIZE_MINIMIZED; SendMessage( hwnd, WM_SIZE, wp, MAKELONG(wndPtr->rectClient.right-wndPtr->rectClient.left, wndPtr->rectClient.bottom-wndPtr->rectClient.top)); } return 0; } case WM_ERASEBKGND: case WM_ICONERASEBKGND: { if (!(classPtr = CLASS_FindClassPtr( wndPtr->hClass ))) return 0; if (!classPtr->wc.hbrBackground) return 0; if (classPtr->wc.hbrBackground <= (HBRUSH)(COLOR_MAX+1)) { HBRUSH hbrush; hbrush = CreateSolidBrush( GetSysColor(((DWORD)classPtr->wc.hbrBackground)-1)); FillWindow( GetParent(hwnd), hwnd, (HDC)wParam, hbrush); DeleteObject (hbrush); } else FillWindow( GetParent(hwnd), hwnd, (HDC)wParam, classPtr->wc.hbrBackground ); return 1; } case WM_GETDLGCODE: return 0; case WM_CTLCOLORMSGBOX: case WM_CTLCOLOREDIT: case WM_CTLCOLORLISTBOX: case WM_CTLCOLORBTN: case WM_CTLCOLORDLG: case WM_CTLCOLORSTATIC: SetBkColor( (HDC)wParam, GetSysColor(COLOR_WINDOW) ); SetTextColor( (HDC)wParam, GetSysColor(COLOR_WINDOWTEXT) ); return (LONG)sysColorObjects.hbrushWindow; case WM_CTLCOLORSCROLLBAR: SetBkColor( (HDC)wParam, RGB(255, 255, 255) ); SetTextColor( (HDC)wParam, RGB(0, 0, 0) ); UnrealizeObject( sysColorObjects.hbrushScrollbar ); return (LONG)sysColorObjects.hbrushScrollbar; case WM_CTLCOLOR: { if (HIWORD(lParam) == CTLCOLOR_SCROLLBAR) { SetBkColor( (HDC)wParam, RGB(255, 255, 255) ); SetTextColor( (HDC)wParam, RGB(0, 0, 0) ); UnrealizeObject( sysColorObjects.hbrushScrollbar ); return (LONG)sysColorObjects.hbrushScrollbar; } else { SetBkColor( (HDC)wParam, GetSysColor(COLOR_WINDOW) ); SetTextColor( (HDC)wParam, GetSysColor(COLOR_WINDOWTEXT) ); return (LONG)sysColorObjects.hbrushWindow; } } case WM_GETTEXT: { if (wParam) { if (wndPtr->hText) { textPtr = (LPSTR)USER_HEAP_LIN_ADDR(wndPtr->hText); if ((int)wParam > (len = strlen(textPtr))) { strcpy((char *)PTR_SEG_TO_LIN(lParam), textPtr); return (DWORD)len; } } } return 0; } case WM_GETTEXTLENGTH: { if (wndPtr->hText) { textPtr = (LPSTR)USER_HEAP_LIN_ADDR(wndPtr->hText); return (DWORD)strlen(textPtr); } return 0; } case WM_SETTEXT: DEFWND_SetText( hwnd, (LPSTR)PTR_SEG_TO_LIN(lParam) ); NC_HandleNCPaint( hwnd , (HRGN)1 ); /* Repaint caption */ return 0; case WM_SETCURSOR: if (wndPtr->dwStyle & WS_CHILD) if (SendMessage(wndPtr->parent->hwndSelf, WM_SETCURSOR, wParam, lParam)) return TRUE; return NC_HandleSetCursor( hwnd, wParam, lParam ); case WM_SYSCOMMAND: { POINT pt = { LOWORD(lParam), HIWORD(lParam) }; return NC_HandleSysCommand( hwnd, wParam, pt ); } case WM_KEYDOWN: if(wParam == VK_F10) iF10Key = VK_F10; break; case WM_SYSKEYDOWN: if( HIWORD(lParam) & KEYDATA_ALT ) { /* if( HIWORD(lParam) & ~KEYDATA_PREVSTATE ) */ if( wParam == VK_MENU && !iMenuSysKey ) iMenuSysKey = 1; else iMenuSysKey = 0; iF10Key = 0; } else if( wParam == VK_F10 ) iF10Key = 1; else if( wParam == VK_ESCAPE && GetKeyState(VK_SHIFT) < 0 ) SendMessage( hwnd, WM_SYSCOMMAND, (WPARAM)SC_KEYMENU, (LPARAM)VK_SPACE); break; case WM_KEYUP: case WM_SYSKEYUP: /* Press and release F10 or ALT */ if( ( wParam == VK_MENU && iMenuSysKey ) || ( wParam == VK_F10 && iF10Key ) ) SendMessage( WIN_GetTopParent(hwnd), WM_SYSCOMMAND, SC_KEYMENU, 0L ); iMenuSysKey = iF10Key = 0; break; case WM_SYSCHAR: iMenuSysKey = 0; if( wParam == VK_RETURN && (wndPtr->dwStyle & WS_MINIMIZE) ) { PostMessage(hwnd, WM_SYSCOMMAND, (WPARAM)SC_RESTORE, 0L ); break; } if( (HIWORD(lParam) & KEYDATA_ALT) && wParam ) { if( wParam == VK_TAB || wParam == VK_ESCAPE ) break; if( wParam == VK_SPACE && (wndPtr->dwStyle & WS_CHILD) ) SendMessage( wndPtr->parent->hwndSelf, msg, wParam, lParam ); else SendMessage(hwnd, WM_SYSCOMMAND, (WPARAM)SC_KEYMENU, (LPARAM)(DWORD)wParam ); } else /* check for Ctrl-Esc */ if( wParam != VK_ESCAPE ) MessageBeep(0); break; case WM_SHOWWINDOW: if( !lParam ) return 0; /* sent from ShowWindow */ if( !(wndPtr->dwStyle & WS_POPUP) || !wndPtr->owner ) return 0; if( wndPtr->dwStyle & WS_VISIBLE ) { if( wParam ) return 0; } else if(!wParam ) return 0; ShowWindow(hwnd,(wParam)? SW_SHOWNOACTIVATE: SW_HIDE); break; case WM_CANCELMODE: /* EndMenu() should be called if in menu state but currently it's impossible to detect - menu code should be updated*/ if( GetCapture() == hwnd ) ReleaseCapture(); break; case WM_VKEYTOITEM: case WM_CHARTOITEM: return -1; case WM_DROPOBJECT: return DRAG_FILE; case WM_QUERYDROPOBJECT: if(wndPtr->dwExStyle & WS_EX_ACCEPTFILES) return 1; break; case WM_QUERYDRAGICON: { HICON hI = 0; len = 1; while(len < 64) if( (hI = LoadIcon(wndPtr->hInstance,MAKEINTRESOURCE(len))) ) return (LRESULT)hI; } break; case WM_QUERYOPEN: case WM_QUERYENDSESSION: return 1; } return 0; }