// static LRESULT CALLBACK IGraphicsWin::WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) { if (msg == WM_CREATE) { LPCREATESTRUCT lpcs = (LPCREATESTRUCT) lParam; SetWindowLongPtr(hWnd, GWLP_USERDATA, (LPARAM) (lpcs->lpCreateParams)); int mSec = int(1000.0 / sFPS); SetTimer(hWnd, IPLUG_TIMER_ID, mSec, NULL); SetFocus(hWnd); // gets scroll wheel working straight away return 0; } IGraphicsWin* pGraphics = (IGraphicsWin*) GetWindowLongPtr(hWnd, GWLP_USERDATA); char txt[MAX_PARAM_LEN]; double v; if (!pGraphics || hWnd != pGraphics->mPlugWnd) { return DefWindowProc(hWnd, msg, wParam, lParam); } if (pGraphics->mParamEditWnd && pGraphics->mParamEditMsg == kEditing) { if (msg == WM_RBUTTONDOWN || (msg == WM_LBUTTONDOWN)) { pGraphics->mParamEditMsg = kCancel; return 0; } return DefWindowProc(hWnd, msg, wParam, lParam); } switch (msg) { case WM_TIMER: { if (wParam == IPLUG_TIMER_ID) { if (pGraphics->mParamEditWnd && pGraphics->mParamEditMsg != kNone) { switch (pGraphics->mParamEditMsg) { case kCommit: { SendMessage(pGraphics->mParamEditWnd, WM_GETTEXT, MAX_PARAM_LEN, (LPARAM) txt); if(pGraphics->mEdParam) { IParam::EParamType type = pGraphics->mEdParam->Type(); if ( type == IParam::kTypeEnum || type == IParam::kTypeBool) { int vi = 0; pGraphics->mEdParam->MapDisplayText(txt, &vi); v = (double) vi; } else { v = atof(txt); if (pGraphics->mEdParam->DisplayIsNegated()) { v = -v; } } pGraphics->mEdControl->SetValueFromUserInput(pGraphics->mEdParam->GetNormalized(v)); } else { pGraphics->mEdControl->TextFromTextEntry(txt); } // Fall through. } case kCancel: { SetWindowLongPtr(pGraphics->mParamEditWnd, GWLP_WNDPROC, (LPARAM) pGraphics->mDefEditProc); DestroyWindow(pGraphics->mParamEditWnd); pGraphics->mParamEditWnd = 0; pGraphics->mEdParam = 0; pGraphics->mEdControl = 0; pGraphics->mDefEditProc = 0; } break; } pGraphics->mParamEditMsg = kNone; return 0; // TODO: check this! } IRECT dirtyR; if (pGraphics->IsDirty(&dirtyR)) { RECT r = { dirtyR.L, dirtyR.T, dirtyR.R, dirtyR.B }; InvalidateRect(hWnd, &r, FALSE); if (pGraphics->mParamEditWnd) { IRECT* notDirtyR = pGraphics->mEdControl->GetRECT(); RECT r2 = { notDirtyR->L, notDirtyR->T, notDirtyR->R, notDirtyR->B }; ValidateRect(hWnd, &r2); // make sure we dont redraw the edit box area UpdateWindow(hWnd); pGraphics->mParamEditMsg = kUpdate; } else { UpdateWindow(hWnd); } } } return 0; } case WM_RBUTTONDOWN: case WM_LBUTTONDOWN: case WM_MBUTTONDOWN: pGraphics->HideTooltip(); if (pGraphics->mParamEditWnd) { pGraphics->mParamEditMsg = kCommit; return 0; } SetFocus(hWnd); // Added to get keyboard focus again when user clicks in window SetCapture(hWnd); #ifdef RTAS_API // pass ctrl-start-alt-click or ctrl-start-click to host window (Pro Tools) if ((IsControlKeyDown() && IsOptionKeyDown() && IsCommandKeyDown() ) || (IsControlKeyDown() && IsCommandKeyDown())) { HWND rootHWnd = GetAncestor( hWnd, GA_ROOT); union point { long lp; struct { short x; short y; } s; } mousePoint; // Get global coordinates of local window RECT childRect; GetWindowRect(hWnd, &childRect); // Convert global coords to parent window coords POINT p; p.x = childRect.left; p.y = childRect.top; ScreenToClient(rootHWnd, &p); // offset the local click-event coordinates to the parent window's values mousePoint.lp = lParam; mousePoint.s.x += p.x; mousePoint.s.y += p.y; if( pGraphics->GetParamIdxForPTAutomation(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam)) > -1) { // Send converted coords to parent window's event handler for regular processing LRESULT result = SendMessage(rootHWnd, msg, wParam, mousePoint.lp); } return 0; } #endif pGraphics->OnMouseDown(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam), &GetMouseMod(wParam)); return 0; case WM_MOUSEMOVE: { if (!(wParam & (MK_LBUTTON | MK_RBUTTON))) { if (pGraphics->OnMouseOver(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam), &GetMouseMod(wParam))) { TRACKMOUSEEVENT eventTrack = { sizeof(TRACKMOUSEEVENT), TME_LEAVE, hWnd, HOVER_DEFAULT }; if (pGraphics->TooltipsEnabled()) { int c = pGraphics->GetMouseOver(); if (c != pGraphics->mTooltipIdx) { if (c >= 0) eventTrack.dwFlags |= TME_HOVER; pGraphics->mTooltipIdx = c; pGraphics->HideTooltip(); } } TrackMouseEvent(&eventTrack); } } else if (GetCapture() == hWnd && !pGraphics->mParamEditWnd) { pGraphics->OnMouseDrag(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam), &GetMouseMod(wParam)); } return 0; } case WM_MOUSEHOVER: { pGraphics->ShowTooltip(); return 0; } case WM_MOUSELEAVE: { pGraphics->HideTooltip(); pGraphics->OnMouseOut(); return 0; } case WM_LBUTTONUP: case WM_RBUTTONUP: { ReleaseCapture(); pGraphics->OnMouseUp(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam), &GetMouseMod(wParam)); return 0; } case WM_LBUTTONDBLCLK: { if (pGraphics->OnMouseDblClick(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam), &GetMouseMod(wParam))) { SetCapture(hWnd); } return 0; } case WM_MOUSEWHEEL: { if (pGraphics->mParamEditWnd) { pGraphics->mParamEditMsg = kCancel; return 0; } else { int d = GET_WHEEL_DELTA_WPARAM(wParam) / WHEEL_DELTA; int x = GET_X_LPARAM(lParam), y = GET_Y_LPARAM(lParam); RECT r; GetWindowRect(hWnd, &r); pGraphics->OnMouseWheel(x - r.left, y - r.top, &GetMouseMod(wParam), d); return 0; } } case WM_KEYDOWN: { bool handle = true; int key; if (wParam == VK_SPACE) key = KEY_SPACE; else if (wParam == VK_UP) key = KEY_UPARROW; else if (wParam == VK_DOWN) key = KEY_DOWNARROW; else if (wParam == VK_LEFT) key = KEY_LEFTARROW; else if (wParam == VK_RIGHT) key = KEY_RIGHTARROW; else if (wParam >= '0' && wParam <= '9') key = KEY_DIGIT_0+wParam-'0'; else if (wParam >= 'A' && wParam <= 'Z') key = KEY_ALPHA_A+wParam-'A'; else if (wParam >= 'a' && wParam <= 'z') key = KEY_ALPHA_A+wParam-'a'; else handle = false; if (handle) { POINT p; GetCursorPos(&p); ScreenToClient(hWnd, &p); handle = pGraphics->OnKeyDown(p.x, p.y, key); } if (!handle) { HWND rootHWnd = GetAncestor( hWnd, GA_ROOT); SendMessage(rootHWnd, WM_KEYDOWN, wParam, lParam); return DefWindowProc(hWnd, msg, wParam, lParam); } else return 0; } case WM_KEYUP: { HWND rootHWnd = GetAncestor(hWnd, GA_ROOT); SendMessage(rootHWnd, msg, wParam, lParam); return DefWindowProc(hWnd, msg, wParam, lParam); } case WM_PAINT: { RECT r; if (GetUpdateRect(hWnd, &r, FALSE)) { IRECT ir(r.left, r.top, r.right, r.bottom); pGraphics->Draw(&ir); } return 0; } case WM_CTLCOLOREDIT: { if(!pGraphics->mEdControl) return 0; IText* pText = pGraphics->mEdControl->GetText(); HDC dc = (HDC) wParam; SetBkColor(dc, RGB(pText->mTextEntryBGColor.R, pText->mTextEntryBGColor.G, pText->mTextEntryBGColor.B)); SetTextColor(dc, RGB(pText->mTextEntryFGColor.R, pText->mTextEntryFGColor.G, pText->mTextEntryFGColor.B)); SetBkMode(dc, OPAQUE); return (BOOL)GetStockObject(DC_BRUSH); } case WM_CLOSE: { pGraphics->CloseWindow(); return 0; } #ifdef RTAS_API case WM_MEASUREITEM : { HWND rootHWnd = GetAncestor( hWnd, GA_ROOT ); LRESULT result = SendMessage(rootHWnd, msg, wParam, lParam); return result; } case WM_DRAWITEM : { HWND rootHWnd = GetAncestor( hWnd, GA_ROOT ); LRESULT result = SendMessage(rootHWnd, msg, wParam, lParam); return result; } #endif case WM_SETFOCUS: { return 0; } case WM_KILLFOCUS: { return 0; } } return DefWindowProc(hWnd, msg, wParam, lParam); }
// static LRESULT CALLBACK IGraphicsWin::ParamEditProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) { IGraphicsWin* pGraphics = (IGraphicsWin*) GetWindowLongPtr(hWnd, GWLP_USERDATA); if (pGraphics && pGraphics->mParamEditWnd && pGraphics->mParamEditWnd == hWnd) { pGraphics->HideTooltip(); switch (msg) { case WM_CHAR: { // limit to numbers for text entry on appropriate parameters if(pGraphics->mEdParam) { char c = wParam; if(c == 0x08) break; // backspace switch ( pGraphics->mEdParam->Type() ) { case IParam::kTypeEnum: case IParam::kTypeInt: case IParam::kTypeBool: if (c >= '0' && c <= '9') break; else if (c == '-') break; else if (c == '+') break; else return 0; case IParam::kTypeDouble: if (c >= '0' && c <= '9') break; else if (c == '-') break; else if (c == '+') break; else if (c == '.') break; else return 0; default: break; } } break; } case WM_KEYDOWN: { if (wParam == VK_RETURN) { pGraphics->mParamEditMsg = kCommit; return 0; } break; } case WM_SETFOCUS: { pGraphics->mParamEditMsg = kEditing; break; } case WM_KILLFOCUS: { pGraphics->mParamEditMsg = kCancel; // when another window is focussed, kill the text edit box break; } // handle WM_GETDLGCODE so that we can say that we want the return key message // (normally single line edit boxes don't get sent return key messages) case WM_GETDLGCODE: { if (pGraphics->mEdParam) break; LPARAM lres; // find out if the original control wants it lres = CallWindowProc(pGraphics->mDefEditProc, hWnd, WM_GETDLGCODE, wParam, lParam); // add in that we want it if it is a return keydown if (lParam && ((MSG*)lParam)->message == WM_KEYDOWN && wParam == VK_RETURN) { lres |= DLGC_WANTMESSAGE; } return lres; } case WM_COMMAND: { switch HIWORD(wParam) { case CBN_SELCHANGE: { if (pGraphics->mParamEditWnd) { pGraphics->mParamEditMsg = kCommit; return 0; } } } break; // Else let the default proc handle it. } } return CallWindowProc(pGraphics->mDefEditProc, hWnd, msg, wParam, lParam); }