1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702 |
- #include <dsound.h>
- #include "WinBFApp.h"
- #include "DXRenderDevice.h"
- #include <signal.h>
- #include "../../util/BeefPerf.h"
- #include "DSoundManager.h"
- #include <dwmapi.h>
- #pragma comment(lib, "dwmapi.lib")
- #include "util/AllocDebug.h"
- USING_NS_BF;
- int Beefy::WinBFMenu::mMenuCount = 0;
- int PrintStuff()
- {
- OutputDebugStringA("Hey!\n");
- return 123;
- }
- WinBFMenu::WinBFMenu()
- {
- mIsPlaceholder = false;
- mMenu = NULL;
- mParent = NULL;
- mMenuId = 0;
- }
- ///
- static HICON gMainIcon = NULL;
- static BOOL CALLBACK BFEnumResNameProc(
- HMODULE hModule,
- LPCWSTR lpszType,
- LPWSTR lpszName,
- LONG_PTR lParam
- )
- {
- gMainIcon = ::LoadIconW(hModule, lpszName);
- return FALSE;
- }
- WinBFWindow::WinBFWindow(BFWindow* parent, const StringImpl& title, int x, int y, int width, int height, int windowFlags)
- {
- HINSTANCE hInstance = GetModuleHandle(NULL);
-
- mMinWidth = 128;
- mMinHeight = 128;
- WNDCLASSW wc;
- wc.style = CS_DBLCLKS;
- wc.cbClsExtra = 0;
- wc.cbWndExtra = 0;
- wc.hbrBackground = NULL;
- //wc.hbrBackground = ::CreateSolidBrush(::GetSysColor(COLOR_BTNFACE));
- wc.hCursor = NULL;
- //wc.hIcon = (HICON) ::LoadImageA(hInstance, "MainIcon", IMAGE_ICON, 0, 0, 0);
- //wc.hIcon = (HICON) ::LoadImageA(hInstance, MAKEINTRESOURCEA(32512), IMAGE_ICON, 0, 0, 0);
- if (gMainIcon != NULL)
- {
- wc.hIcon = gMainIcon;
- }
- else
- {
- wc.hIcon = (HICON) ::LoadIconA(hInstance, "MainIcon");
- if (wc.hIcon == NULL)
- {
- EnumResourceNamesW(hInstance, (LPCWSTR)RT_GROUP_ICON, BFEnumResNameProc, 0);
- wc.hIcon = gMainIcon;
- }
- }
- wc.hInstance = hInstance;
- wc.lpfnWndProc = WindowProcStub;
- wc.lpszClassName = L"BFWindow";
- wc.lpszMenuName = NULL;
- RegisterClassW(&wc);
-
- int requestedX = x;
- int requestedY = y;
- int aWindowFlags = 0;
- bool hasDestAlpha = (windowFlags & BFWINDOW_DEST_ALPHA) != 0;
- if (windowFlags & BFWINDOW_MENU)
- {
- WinBFMenu* aMenu = new WinBFMenu();
- aMenu->mMenu = ::CreateMenu();
- mHMenuMap[aMenu->mMenu] = aMenu;
- mMenu = aMenu;
- }
-
- int windowFlagsEx = /*WS_EX_COMPOSITED |*/ WS_EX_LAYERED;
- if (windowFlags & BFWINDOW_TOOLWINDOW)
- windowFlagsEx |= WS_EX_TOOLWINDOW;
- if (windowFlags & BFWINDOW_BORDER)
- aWindowFlags |= WS_BORDER;
- if (windowFlags & BFWINDOW_THICKFRAME)
- aWindowFlags |= WS_THICKFRAME;
- if ((windowFlags & BFWINDOW_RESIZABLE) && (!hasDestAlpha))
- aWindowFlags |= WS_SIZEBOX;
- if (windowFlags & BFWINDOW_SYSMENU)
- aWindowFlags |= WS_SYSMENU;
- if (windowFlags & BFWINDOW_CAPTION)
- aWindowFlags |= WS_CAPTION;
- else
- aWindowFlags |= WS_POPUP;
- if (windowFlags & BFWINDOW_MINIMIZE)
- aWindowFlags |= WS_MINIMIZEBOX;
- if (windowFlags & BFWINDOW_MAXIMIZE)
- aWindowFlags |= WS_MAXIMIZEBOX;
- if ((windowFlags & BFWINDOW_TOPMOST) && (parent == NULL))
- windowFlagsEx |= WS_EX_TOPMOST;
- if (windowFlags & BFWINDOW_CLIENT_SIZED)
- {
- RECT rect = {0, 0, width, height};
- AdjustWindowRectEx(&rect, aWindowFlags, mMenu != NULL, windowFlagsEx);
- x += rect.left;
- y += rect.top;
- width = rect.right - rect.left;
- height = rect.bottom - rect.top;
- }
-
- if (windowFlags & BFWINDOW_POPUP_POSITION)
- {
- RECT desktopRect;
- ::SystemParametersInfo(SPI_GETWORKAREA, NULL, &desktopRect, NULL);
- if (x + width >= desktopRect.right)
- x = BF_MAX((int)desktopRect.left, requestedX - width);
- if (y + height >= desktopRect.bottom)
- y = BF_MAX((int)desktopRect.top, requestedY - height);
- }
-
- mFlags = windowFlags;
- mMouseVisible = true;
- mParent = parent;
- HWND parentHWnd = NULL;
- if (parent != NULL)
- parentHWnd = ((WinBFWindow*) parent)->mHWnd;
- if (mMenu != NULL)
- {
- WinBFMenu* placeholderMenu = (WinBFMenu*) AddMenuItem(mMenu, 0, ": Placeholder Menu Item :", NULL, NULL, false, -1, false);
- placeholderMenu->mIsPlaceholder = true;
- }
-
- mHWnd = CreateWindowExW(windowFlagsEx, L"BFWindow", UTF8Decode(title).c_str(),
- aWindowFlags,
- x, y,
- width,
- height,
- parentHWnd,
- (mMenu != NULL) ? ((WinBFMenu*) mMenu)->mMenu : NULL,
- hInstance,
- 0);
-
- if ((windowFlags & BFWINDOW_ALPHA_MASK) == 0)
- SetLayeredWindowAttributes(mHWnd, 0, 255, 0);
- HWND relativeWindow = NULL;
- if ((windowFlags & BFWINDOW_TOPMOST) && (parent == NULL))
- relativeWindow = HWND_TOP;
- int showFlags = SWP_SHOWWINDOW;
- mHasFocus = true;
- mSoftHasFocus = true;
- if (windowFlags & BFWINDOW_FAKEFOCUS)
- {
- showFlags |= SWP_NOACTIVATE;
- if (windowFlags & BFWINDOW_NO_ACTIVATE)
- {
- mHasFocus = false;
- mSoftHasFocus = false;
- }
- }
- else if (windowFlags & BFWINDOW_NO_ACTIVATE)
- {
- showFlags |= SWP_NOACTIVATE;
- mHasFocus = false;
- mSoftHasFocus = false;
- }
- SetWindowPos(mHWnd, relativeWindow, x, y, width, height, showFlags);
-
- SetTimer(mHWnd, 0, 10, NULL);
-
- mIsMouseInside = false;
- mRenderWindow = new DXRenderWindow((DXRenderDevice*) gBFApp->mRenderDevice, mHWnd, (windowFlags & BFWINDOW_FULLSCREEN) == 0);
- mRenderWindow->mWindow = this;
- gBFApp->mRenderDevice->AddRenderWindow(mRenderWindow);
- SetWindowLongPtr(mHWnd, GWLP_USERDATA, (LONG_PTR)this);
- mIsMenuKeyHandled = false;
- mAlphaMaskBitmap = NULL;
- mAlphaMaskDC = NULL;
- mAlphaMaskPixels = NULL;
- mAlphaMaskWidth = 0;
- mAlphaMaskHeight = 0;
- mNeedsStateReset = false;
- if (windowFlags & BFWINDOW_DEST_ALPHA)
- {
- MARGINS dWMMargins = {-1, -1, -1, -1};
- DwmExtendFrameIntoClientArea(mHWnd, &dWMMargins);
- }
- if (windowFlags & BFWINDOW_MODAL)
- {
- EnableWindow(parentHWnd, FALSE);
- }
-
- if (parent != NULL)
- {
- auto winParent = (WinBFWindow*)parent;
- BF_ASSERT(winParent->mHWnd);
- parent->mChildren.push_back(this);
- }
- }
- WinBFWindow::~WinBFWindow()
- {
- for (auto child : mChildren)
- {
- NOP;
- }
- if (mHWnd != NULL)
- Destroy();
- }
- void* WinBFWindow::GetUnderlying()
- {
- return mHWnd;
- }
- void WinBFWindow::Destroy()
- {
- if (mAlphaMaskDC != NULL)
- DeleteDC(mAlphaMaskDC);
- mAlphaMaskDC = NULL;
- if (mAlphaMaskBitmap != NULL)
- DeleteObject(mAlphaMaskBitmap);
- mAlphaMaskBitmap = NULL;
- for (auto& menu : mMenuIDMap)
- {
- delete menu.mValue;
- }
- mMenuIDMap.Clear();
- ::DestroyWindow(mHWnd);
- BF_ASSERT(mHWnd == NULL);
- }
- bool WinBFWindow::TryClose()
- {
- SendMessage(mHWnd, WM_CLOSE, 0, 0);
- return mHWnd == NULL;
- }
- void WinBFWindow::SetTitle(const char* title)
- {
- SetWindowTextA(mHWnd, title);
- }
- void WinBFWindow::LostFocus(BFWindow* newFocus)
- {
- WinBFWindow* bfNewFocus = (WinBFWindow*)newFocus;
- mSoftHasFocus = false;
- for (int i = 0; i < KEYCODE_MAX; i++)
- {
- // Only transfer mode keys
- if (mIsKeyDown[i])
- {
- mIsKeyDown[i] = false;
- mKeyUpFunc(this, i);
- if ((newFocus != NULL) &&
- ((i == VK_SHIFT) || (i == VK_CONTROL) || (i == VK_MENU)))
- {
- newFocus->mIsKeyDown[i] = true;
- newFocus->mKeyDownFunc(newFocus, i, 0);
- }
- }
- }
- }
- void WinBFWindow::SetForeground()
- {
- if (mFlags & BFWINDOW_FAKEFOCUS)
- {
- mHasFocus = true;
- mSoftHasFocus = true;
- return;
- }
- ::SetFocus(mHWnd);
- ::SetForegroundWindow(mHWnd);
- //OutputDebugStrF("SetForeground %p\n", mHWnd);
- }
- static POINT gLastScreenMouseCoords = { -1, -1 };
- void WinBFWindow::RehupMouseOver(bool isMouseOver)
- {
- if ((!mIsMouseInside) && (isMouseOver))
- {
- TRACKMOUSEEVENT tme;
- tme.cbSize = sizeof(TRACKMOUSEEVENT);
- tme.dwFlags = TME_LEAVE;
- tme.hwndTrack = mHWnd;
- TrackMouseEvent(&tme);
- mIsMouseInside = true;
- }
- if ((mIsMouseInside) && (!isMouseOver))
- {
- mIsMouseInside = false;
- mMouseLeaveFunc(this);
- }
- }
- LRESULT WinBFWindow::WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
- {
- WinBFApp* app = (WinBFApp*) gBFApp;
- if (app == NULL)
- {
- PrintStuff();
- }
- switch (uMsg)
- {
- case WM_KEYDOWN:
- case WM_KEYUP:
- case WM_SYSKEYDOWN:
- case WM_CHAR:
- for (auto child : mChildren)
- {
- auto childWindow = (WinBFWindow*)child;
- if ((childWindow->mSoftHasFocus) && (childWindow->mFlags & BFWINDOW_FAKEFOCUS))
- {
- return childWindow->WindowProc(hWnd, uMsg, wParam, lParam);
- }
- }
- break;
- }
- switch (uMsg)
- {
- case WM_CLOSE:
- {
- //OutputDebugStrF("WM_CLOSE %08X NewFocus:%08X\n", hWnd, GetFocus());
- if (mCloseQueryFunc(this) != 0)
- gBFApp->RemoveWindow(this);
- HWND newFocus = GetFocus();
- for (auto window : gBFApp->mWindowList)
- {
- WinBFWindow* winWindow = (WinBFWindow*)window;
- if (winWindow->mHWnd == newFocus)
- {
- while (true)
- {
- WinBFWindow* altFocusWindow = NULL;
- for (auto checkChild : winWindow->mChildren)
- {
- auto checkWinChild = (WinBFWindow*)checkChild;
- if (checkWinChild->mFlags & BFWINDOW_FAKEFOCUS)
- altFocusWindow = checkWinChild;
- }
- if (altFocusWindow == NULL)
- break;
- winWindow = altFocusWindow;
- }
- winWindow->mHasFocus = true;
- winWindow->mSoftHasFocus = true;
- winWindow->mGotFocusFunc(winWindow);
- }
- }
- return 0;
- }
- break;
- case WM_DESTROY:
- /*if (mFlags & BFWINDOW_QUIT_ON_CLOSE)
- {
- gBFApp->mRunning = false;
- }*/
- SetWindowLongPtr(mHWnd, GWLP_USERDATA, (LONG_PTR)0);
- mHWnd = NULL;
- if (!mChildren.IsEmpty())
- {
- NOP;
- }
- break;
- }
- LRESULT result = 0;
- bool doResult = false;
- if (!app->mInMsgProc)
- {
- if (mNeedsStateReset)
- {
- for (int i = 0; i < KEYCODE_MAX; i++)
- {
- if (mIsKeyDown[i])
- {
- mIsKeyDown[i] = false;
- mKeyUpFunc(this, i);
- }
- }
- POINT mousePoint;
- ::GetCursorPos(&mousePoint);
- ::ScreenToClient(hWnd, &mousePoint);
- for (int i = 0; i < MOUSEBUTTON_MAX; i++)
- {
- if (mIsMouseDown[i])
- {
- mMouseUpFunc(this, mousePoint.x, mousePoint.y, i);
- mIsMouseDown[i] = false;
- }
- }
- //OutputDebugStrF("Rehup ReleaseCapture()\n");
- ReleaseCapture();
-
- mNeedsStateReset = false;
- mIsMouseInside = false;
- }
-
- WinBFWindow* menuTarget = this;
- if (mFlags & BFWINDOW_USE_PARENT_MENU)
- menuTarget = ((WinBFWindow*)mParent);
- auto* menuIDMap = &menuTarget->mMenuIDMap;
- auto* hMenuMap = &menuTarget->mHMenuMap;
- app->mInMsgProc = true;
- switch (uMsg)
- {
- case WM_SIZE:
- mRenderWindow->Resized();
- if (mMovedFunc != NULL)
- mMovedFunc(this);
- break;
- case WM_PAINT:
- break;
- case WM_NCHITTEST:
- {
- //OutputDebugStrF("WM_NCHITTEST %X\n", mHWnd);
- int x = (short)LOWORD(lParam);
- int y = (short)HIWORD(lParam);
- result = mHitTestFunc(this, x, y);
- doResult = (result != -3);
- }
- break;
- case WM_LBUTTONDOWN:
- case WM_RBUTTONDOWN:
- case WM_MBUTTONDOWN:
- case WM_LBUTTONDBLCLK:
- case WM_RBUTTONDBLCLK:
- case WM_LBUTTONUP:
- case WM_RBUTTONUP:
- case WM_MBUTTONUP:
- case WM_MOUSEWHEEL:
- case WM_MOUSEMOVE:
- {
- int x = (short)LOWORD(lParam);
- int y = (short)HIWORD(lParam);
- bool releaseCapture = false;
- POINT point = {x, y};
- if (uMsg != WM_MOUSEWHEEL)
- ::ClientToScreen(hWnd, &point);
- if ((uMsg == WM_MOUSEMOVE) && (point.x == gLastScreenMouseCoords.x) && (point.y == gLastScreenMouseCoords.y))
- {
- // Don't process a WM_MOUSEMOVE if it's at the same point at the last mouse event
- // This keeps us from getting a WM_MOUSEMOVE when we popup a window under the current cursor location.
- // This is important for keyboard cursor control - so the first down arrow keypress selects the first item in the list
- // irregardless of the mouse cursor position.
- break;
- }
- gLastScreenMouseCoords.x = point.x;
- gLastScreenMouseCoords.y = point.y;
- HWND windowAtPoint = ::WindowFromPoint(point);
- bool isMouseOver = windowAtPoint == hWnd;
- RehupMouseOver(isMouseOver);
- //OutputDebugStrF("HWnd: %X Focus Window: %X Capture: %X\n", hWnd, windowAtPoint, ::GetCapture());
-
- bool checkNonTransparentMousePosition = mNonExclusiveMouseCapture;
- switch (uMsg)
- {
- case WM_LBUTTONDOWN:
- //OutputDebugStrF("WM_LBUTTONDOWN Capture HWnd: %X\n", hWnd);
- SetCapture(hWnd);
- mIsMouseDown[0] = true;
- mMouseDownFunc(this, x, y, 0, 1);
- break;
- case WM_RBUTTONDOWN:
- //OutputDebugStrF("WM_RBUTTONDOWN Capture HWnd: %X\n", hWnd);
- SetCapture(hWnd);
- mIsMouseDown[1] = true;
- mMouseDownFunc(this, x, y, 1, 1);
- break;
- case WM_MBUTTONDOWN:
- SetCapture(hWnd);
- mIsMouseDown[2] = true;
- mMouseDownFunc(this, x, y, 2, 1);
- break;
- case WM_LBUTTONDBLCLK:
- SetCapture(hWnd);
- mMouseDownFunc(this, x, y, 0, 2);
- break;
- case WM_RBUTTONDBLCLK:
- SetCapture(hWnd);
- mMouseDownFunc(this, x, y, 1, 2);
- break;
- case WM_MBUTTONDBLCLK:
- SetCapture(hWnd);
- mMouseDownFunc(this, x, y, 2, 2);
- break;
- case WM_LBUTTONUP:
- releaseCapture = true;
- mIsMouseDown[0] = false;
- mMouseUpFunc(this, x, y, 0);
- break;
- case WM_RBUTTONUP:
- releaseCapture = true;
- mIsMouseDown[1] = false;
- mMouseUpFunc(this, x, y, 1);
- break;
- case WM_MBUTTONUP:
- releaseCapture = true;
- mIsMouseDown[2] = false;
- mMouseUpFunc(this, x, y, 2);
- break;
- case WM_MOUSEWHEEL:
- {
- WinBFWindow* cursorWindow = this;
- if ((gBFApp->mWindowList.size() > 1) && (GetCapture() == NULL))
- {
- // See if our mouse is down and has entered into another window's space
- POINT point = { x, y };
- HWND windowAtPoint = ::WindowFromPoint(point);
- BFWindowList::iterator itr = gBFApp->mWindowList.begin();
- while (itr != gBFApp->mWindowList.end())
- {
- WinBFWindow* aWindow = (WinBFWindow*) *itr;
- LONG targetStyle = ::GetWindowLong(aWindow->mHWnd, GWL_EXSTYLE);
- if ((::IsWindowEnabled(aWindow->mHWnd)) && ((targetStyle & WS_EX_TRANSPARENT) == 0))
- {
- if (aWindow->mHWnd == windowAtPoint)
- {
- aWindow->mIsMouseInside = true;
- cursorWindow = aWindow;
- }
- }
- ++itr;
- }
- }
- if ((cursorWindow != this) && (mIsMouseInside))
- {
- mMouseLeaveFunc(this);
- mIsMouseInside = false;
- }
- POINT pt = {x, y};
- ScreenToClient(cursorWindow->mHWnd, &pt);
- int delta = ((int16)HIWORD(wParam)) / 120;
- mMouseWheelFunc(cursorWindow, pt.x, pt.y, delta);
- }
- break;
- case WM_MOUSEMOVE:
- {
- //OutputDebugStrF("WM_MOUSEMOVE %d\n", hWnd);
- mMouseMoveFunc(this, x, y);
- // If we are dragging a transparent window then check for mouse positions under cursor
- HWND captureWindow = GetCapture();
- if (captureWindow != NULL)
- {
- LONG captureStyle = ::GetWindowLong(captureWindow, GWL_EXSTYLE);
- if ((captureStyle & WS_EX_TRANSPARENT) != 0)
- checkNonTransparentMousePosition = true;
- }
- }
- break;
- }
- if ((checkNonTransparentMousePosition) && (gBFApp->mWindowList.size() > 1))
- {
- // See if our mouse is down and has entered into another window's space
- POINT point = { x, y };
- ::ClientToScreen(hWnd, &point);
- HWND windowAtPoint = ::WindowFromPoint(point);
- BFWindowList::iterator itr = gBFApp->mWindowList.begin();
- while (itr != gBFApp->mWindowList.end())
- {
- WinBFWindow* aWindow = (WinBFWindow*) *itr;
- if (aWindow != this)
- {
- LONG myStyle = ::GetWindowLong(mHWnd, GWL_EXSTYLE);
- LONG targetStyle = ::GetWindowLong(aWindow->mHWnd, GWL_EXSTYLE);
- if ((targetStyle & WS_EX_TRANSPARENT) == 0)
- {
- if (aWindow->mHWnd == windowAtPoint)
- {
- POINT clientPt = point;
- ::ScreenToClient(aWindow->mHWnd, &clientPt);
- aWindow->mMouseProxyMoveFunc(aWindow, clientPt.x, clientPt.y);
- aWindow->mIsMouseInside = true;
- }
- else if (aWindow->mIsMouseInside)
- {
- aWindow->mMouseLeaveFunc(aWindow);
- aWindow->mIsMouseInside = false;
- }
- }
- }
- ++itr;
- }
- }
- if (releaseCapture)
- {
- for (int i = 0; i < MOUSEBUTTON_MAX; i++)
- if (mIsMouseDown[i])
- releaseCapture = false;
- }
- if (releaseCapture)
- {
- //OutputDebugStrF("ReleaseCapture\n");
- ReleaseCapture();
- BFWindowList::iterator itr = gBFApp->mWindowList.begin();
- while (itr != gBFApp->mWindowList.end())
- {
- WinBFWindow* aWindow = (WinBFWindow*) *itr;
- if ((aWindow != this) && (aWindow->mIsMouseInside))
- {
- aWindow->mMouseLeaveFunc(aWindow);
- aWindow->mIsMouseInside = false;
- }
- ++itr;
- }
- }
- }
- break;
-
- case WM_COMMAND:
- {
- WinBFMenu* aMenu = (*menuIDMap)[(uint32)wParam];
- if (aMenu != NULL)
- menuTarget->mMenuItemSelectedFunc(menuTarget, aMenu);
- }
- break;
- case WM_APPCOMMAND:
- {
- if ((mFlags & BFWINDOW_CAPTURE_MEDIA_KEYS) != 0)
- {
- int cmd = GET_APPCOMMAND_LPARAM(lParam);
- int uDevice = GET_DEVICE_LPARAM(lParam);
- int dwKeys = GET_KEYSTATE_LPARAM(lParam);
- int key = cmd | 0x1000;
- mKeyDownFunc(this, key, false);
- result = TRUE;
- doResult = true;
- }
- }
- break;
- case WM_INITMENUPOPUP:
- {
- if (mIsKeyDown[VK_MENU])
- {
- mKeyUpFunc(this, (int)VK_MENU);
- mIsKeyDown[VK_MENU] = false;
- }
- HMENU hMenu = (HMENU) wParam;
- WinBFMenu* aMenu = (*hMenuMap)[hMenu];
- if (aMenu != NULL)
- menuTarget->mMenuItemSelectedFunc(menuTarget, aMenu);
- }
- break;
- case WM_MOUSEACTIVATE:
- if (mFlags & BFWINDOW_NO_MOUSE_ACTIVATE)
- {
- doResult = true;
- result = MA_NOACTIVATE;
- }
- else if (mFlags & BFWINDOW_FAKEFOCUS)
- {
- doResult = true;
- result = MA_NOACTIVATE;
- SetForeground();
- }
- break;
- case WM_ACTIVATE:
- //OutputDebugStrF("WM_ACTIVATE %p\n", hWnd);
- break;
- case WM_KILLFOCUS:
- //OutputDebugStrF("WM_KILLFOCUS %p\n", hWnd);
- mHasFocus = false;
- mSoftHasFocus = false;
- LostFocus(NULL);
- mLostFocusFunc(this);
- break;
- case WM_SETFOCUS:
- //OutputDebugStrF("WM_SETFOCUS %p\n", hWnd);
- mHasFocus = true;
- mSoftHasFocus = true;
- mGotFocusFunc(this);
- break;
- case WM_ENTERMENULOOP:
- //OutputDebugStrF("WM_ENTERMENULOOP %08X\n", hWnd);
- if (mMenu != NULL)
- mNeedsStateReset = true;
- break;
- case WM_EXITMENULOOP:
- //OutputDebugStrF("WM_EXITMENULOOP %08X\n", hWnd);
- if (mMenu != NULL)
- mNeedsStateReset = true;
- break;
- case WM_NCMOUSELEAVE:
- mIsMouseInside = false;
- mMouseLeaveFunc(this);
- break;
- case WM_CHAR:
- {
- /*if (wParam == 'z')
- {
- ID3D11Debug* pD3DDebug = NULL;
- HRESULT hr = ((DXRenderDevice*)mRenderWindow->mRenderDevice)->mD3DDevice->QueryInterface(__uuidof(ID3D11Debug), (void**)&pD3DDebug);
- if (pD3DDebug != NULL)
- {
- pD3DDebug->ReportLiveDeviceObjects(D3D11_RLDO_DETAIL);
- pD3DDebug->Release();
- }
- }*/
- if ((!mIsKeyDown[VK_MENU]) && (!mIsKeyDown[VK_CONTROL]))
- {
- for (int i = 0; i < (lParam & 0x7FFF); i++)
- mKeyCharFunc(this, (WCHAR)wParam);
- }
- }
- break;
- case WM_MENUCHAR:
- if (mIsMenuKeyHandled)
- {
- result = MNC_CLOSE << 16;
- doResult = true;
- }
- break;
- case WM_SYSKEYDOWN:
- case WM_KEYDOWN:
- {
- mIsMenuKeyHandled = false;
- int keyCode = (int) wParam;
- if (keyCode == VK_APPS)
- break; // This is handled in WM_CONTEXTMENU
- mIsKeyDown[keyCode] = true;
-
- for (auto kv : *menuIDMap)
- {
- WinBFMenu* aMenu = kv.mValue;
- if ((aMenu->mKeyCode == keyCode) &&
- (aMenu->mKeyShift == mIsKeyDown[VK_SHIFT]) &&
- (aMenu->mKeyCtrl == mIsKeyDown[VK_CONTROL]) &&
- (aMenu->mKeyAlt == mIsKeyDown[VK_MENU]))
- {
- mIsMenuKeyHandled = true;
- menuTarget->mMenuItemSelectedFunc(menuTarget, aMenu);
- doResult = true;
- break;
- }
- }
- if (!mIsMenuKeyHandled)
- {
- if (mKeyDownFunc(this, (int) wParam, (lParam & 0x7FFF) != 0))
- {
- mIsMenuKeyHandled = true;
- doResult = true;
- }
- }
- }
- break;
- case WM_SYSCHAR:
- {
- int keyCode = toupper((int) wParam);
- for (auto& menuKV : *menuIDMap)
- {
- WinBFMenu* aMenu = menuKV.mValue;
- if ((aMenu->mKeyCode == keyCode) &&
- (aMenu->mKeyShift == mIsKeyDown[VK_SHIFT]) &&
- (aMenu->mKeyCtrl == mIsKeyDown[VK_CONTROL]) &&
- (aMenu->mKeyAlt == mIsKeyDown[VK_MENU]))
- {
- doResult = true;
- break;
- }
- }
- if (!mIsKeyDown[VK_MENU])
- {
- // If we don't have the alt key down then we assume we must have
- // had keyups forced by losing focus from the mMenuItemSelectedFunc
- doResult = true;
- }
- }
- break;
- case WM_SYSKEYUP:
- case WM_KEYUP:
- {
- int keyCode = (int) wParam;
- if (mIsKeyDown[keyCode])
- {
- mKeyUpFunc(this, (int) wParam);
- mIsKeyDown[keyCode] = false;
- }
- }
- break;
- case WM_SYSCOMMAND:
- // Ignore F10
- if ((wParam == SC_KEYMENU) && (lParam == 0))
- {
- doResult = true;
- result = 0;
- }
- break;
- case WM_CONTEXTMENU:
- {
- int x = (short)LOWORD(lParam);
- int y = (short)HIWORD(lParam);
- if ((x == -1) && (y == -1))
- {
- mKeyDownFunc(this, VK_APPS, false);
- mKeyUpFunc(this, VK_APPS);
- }
- }
- break;
- case WM_TIMER:
- if (gBFApp->mSysDialogCnt == 0)
- {
- auto checkNonFake = this;
- while (checkNonFake->mFlags & BFWINDOW_FAKEFOCUS)
- {
- checkNonFake = (WinBFWindow*)checkNonFake->mParent;
- }
- bool isFocused = GetForegroundWindow() == checkNonFake->mHWnd;
-
- if ((!isFocused) && (mHasFocus))
- {
- mSoftHasFocus = false;
- mHasFocus = false;
- LostFocus(NULL);
- mLostFocusFunc(this);
- //OutputDebugStrF("Timer detected lost focus %p\r\n", hWnd);
- }
- else if ((isFocused) && (!mHasFocus) && (checkNonFake == this))
- {
- mHasFocus = true;
- mSoftHasFocus = true;
- mGotFocusFunc(this);
- //OutputDebugStrF("Timer detected got focus %p\r\n", hWnd);
- }
- mSoftHasFocus = mHasFocus;
- gBFApp->Process();
- // Don't do anything with 'this' after Process, we may be deleted now
- doResult = true;
- result = 0;
- }
- break;
- case WM_SETCURSOR:
- gBFApp->PhysSetCursor();
- break;
- case WM_GETMINMAXINFO:
- {
- MINMAXINFO* minMaxInfo = (MINMAXINFO*)lParam;
- minMaxInfo->ptMinTrackSize.x = mMinWidth;
- minMaxInfo->ptMinTrackSize.y = mMinHeight;
- result = 0;
- doResult = true;
- }
- break;
-
- case WM_MOVE:
- case WM_MOVING:
- if (mMovedFunc != NULL)
- mMovedFunc(this);
- break;
- case WM_SIZING:
- mRenderWindow->Resized();
- if (mMovedFunc != NULL)
- mMovedFunc(this);
- if (gBFApp->mSysDialogCnt == 0)
- gBFApp->Process();
- break;
- }
-
- app->mInMsgProc = false;
- }
- else
- {
- // We got messages we couldn't process (due to reentrancy)
- switch (uMsg)
- {
- case WM_LBUTTONUP:
- case WM_RBUTTONUP:
- case WM_MBUTTONUP:
- case WM_MOUSEMOVE:
- case WM_KEYUP:
- case WM_MOUSELEAVE:
- mNeedsStateReset = true;
- break;
- }
- }
- if (doResult)
- return result;
- return DefWindowProc(hWnd, uMsg, wParam, lParam);
- }
- LRESULT CALLBACK WinBFWindow::WindowProcStub(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
- {
- WinBFWindow* aWindow = (WinBFWindow*) GetWindowLongPtr(hWnd, GWLP_USERDATA);
- if (aWindow != NULL)
- return aWindow->WindowProc(hWnd, Msg, wParam, lParam);
- else
- return DefWindowProc(hWnd, Msg, wParam, lParam);
- }
- //
- static int WinBFReportHook( int reportType, char *message, int *returnValue )
- {
- if (reportType == 0)
- return 0;
- //__crtMessageWindowW(nRptType, szFile, (nLine ? szLineMessage : NULL), szModule, szUserMessage);;
- if (gBFApp)
- ((WinBFApp*) gBFApp)->mInMsgProc = true;
- int nCode = ::MessageBoxA(NULL, message,
- "Microsoft Visual C++ Debug Library",
- MB_TASKMODAL|MB_ICONHAND|MB_ABORTRETRYIGNORE|MB_SETFOREGROUND);
- if (gBFApp)
- ((WinBFApp*) gBFApp)->mInMsgProc = false;
- /* Abort: abort the program */
- if (IDABORT == nCode)
- {
- /* note that it is better NOT to call abort() here, because the
- * default implementation of abort() will call Watson
- */
- /* raise abort signal */
- raise(SIGABRT);
- /* We usually won't get here, but it's possible that
- SIGABRT was ignored. So exit the program anyway. */
- _exit(3);
- }
- /* Retry: return 1 to call the debugger */
- if (IDRETRY == nCode)
- return 1;
- /* Ignore: continue execution */
- return 0;
-
-
- return 1;
- }
- extern HINSTANCE gDLLInstance;
- WinBFApp::WinBFApp()
- {
- #ifndef BF_MINGW
- //_CrtSetReportHook(WinBFReportHook);
- #endif
- mRunning = false;
- mRenderDevice = NULL;
- mInstallDir = "Hey";
- WCHAR aStr[MAX_PATH];
- GetModuleFileNameW(gDLLInstance, aStr, MAX_PATH);
- mInstallDir = UTF8Encode(aStr);
- int a2DArray[3][4] = {{1, 2, 3, 4}, {5, 6, 7, 8}, {9, 10, 11, 12}};
- int lastSlash = (int) mInstallDir.LastIndexOf(L'\\');
- if (lastSlash != -1)
- mInstallDir = mInstallDir.Substring(0, lastSlash + 1);
- mDataDir = mInstallDir;
- mInMsgProc = false;
- mDSoundManager = NULL;
- }
- WinBFApp::~WinBFApp()
- {
- delete mRenderDevice;
- delete mDSoundManager;
- }
- void WinBFApp::Init()
- {
- BP_ZONE("WinBFApp::Init");
- mRunning = true;
- mInMsgProc = false;
-
- mRenderDevice = new DXRenderDevice();
- mRenderDevice->Init(this);
- }
- void WinBFApp::Run()
- {
- MSG msg;
- while (mRunning)
- {
- while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
- {
- TranslateMessage(&msg);
- DispatchMessage(&msg);
- }
- if (mRunning)
- Process();
- }
- }
- void WinBFApp::Draw()
- {
- mRenderDevice->FrameStart();
- BFApp::Draw();
- mRenderDevice->FrameEnd();
- }
- void WinBFApp::GetDesktopResolution(int& width, int& height)
- {
- width = ::GetSystemMetrics(SM_CXSCREEN);
- height = ::GetSystemMetrics(SM_CYSCREEN);
- }
- void WinBFApp::GetWorkspaceRect(int& x, int& y, int& width, int& height)
- {
- RECT desktopRect;
- ::SystemParametersInfo(SPI_GETWORKAREA, NULL, &desktopRect, NULL);
- x = desktopRect.left;
- y = desktopRect.top;
- width = desktopRect.right - desktopRect.left;
- height = desktopRect.bottom - desktopRect.top;
- }
- BFWindow* WinBFApp::CreateNewWindow(BFWindow* parent, const StringImpl& title, int x, int y, int width, int height, int windowFlags)
- {
- BFWindow* aWindow = new WinBFWindow(parent, title, x, y, width, height, windowFlags);
- mWindowList.push_back(aWindow);
-
- return aWindow;
- }
- void WinBFApp::RehupMouse()
- {
- HWND windowAtPoint = ::WindowFromPoint(gLastScreenMouseCoords);
- for (auto window : mWindowList)
- {
- auto winWindow = (WinBFWindow*)window;
- winWindow->RehupMouseOver(winWindow->mHWnd == windowAtPoint);
- }
- }
- void WinBFWindow::SetMinimumSize(int minWidth, int minHeight, bool clientSized)
- {
- if (clientSized)
- {
- DWORD windowFlags = ::GetWindowLong(mHWnd, GWL_STYLE);
- DWORD windowFlagsEx = ::GetWindowLong(mHWnd, GWL_EXSTYLE);
- RECT rect = { 0, 0, minWidth, minHeight };
- AdjustWindowRectEx(&rect, windowFlags, mMenu != NULL, windowFlagsEx);
- minWidth = rect.right - rect.left;
- minHeight = rect.bottom - rect.top;
- }
- mMinWidth = minWidth;
- mMinHeight = minHeight;
- if (mHWnd != NULL)
- {
- RECT windowRect;
- ::GetWindowRect(mHWnd, &windowRect);
- bool resized = false;
- if (windowRect.right - windowRect.left < minWidth)
- {
- windowRect.right = windowRect.left + minWidth;
- resized = true;
- }
- if (windowRect.bottom - windowRect.top < minHeight)
- {
- windowRect.bottom = windowRect.top + minHeight;
- resized = true;
- }
- if (resized)
- {
- ::MoveWindow(mHWnd, windowRect.left, windowRect.top, windowRect.right - windowRect.left, windowRect.bottom - windowRect.top, TRUE);
- mRenderWindow->Resized();
- if (mMovedFunc != NULL)
- mMovedFunc(this);
- }
- }
- }
- void WinBFWindow::GetPosition(int* x, int* y, int* width, int* height, int* clientX, int* clientY, int* clientWidth, int* clientHeight)
- {
- RECT windowRect;
- GetWindowRect(mHWnd, &windowRect);
- RECT clientRect;
- GetClientRect(mHWnd, &clientRect);
- if (clientRect.right <= clientRect.left)
- return; // TODO: return failure?
- *x = windowRect.left;
- *y = windowRect.top;
- *width = windowRect.right - windowRect.left;
- *height = windowRect.bottom - windowRect.top;
- *clientWidth = clientRect.right - clientRect.left;
- *clientHeight = clientRect.bottom - clientRect.top;
- POINT startPt = {0, 0};
- ::ClientToScreen(mHWnd, &startPt);
- *clientX = startPt.x;
- *clientY = startPt.y;
- }
- void WinBFWindow::Resize(int x, int y, int width, int height)
- {
- ::MoveWindow(mHWnd, x, y, width, height, FALSE);
- mRenderWindow->Resized();
- if (mMovedFunc != NULL)
- mMovedFunc(this);
- }
- void WinBFApp::PhysSetCursor()
- {
- static HCURSOR cursors [] =
- {
- ::LoadCursor(NULL, IDC_ARROW),
-
- //TODO: mApp->mHandCursor);
- ::LoadCursor(NULL, IDC_HAND),
- //TODO: mApp->mDraggingCursor);
- ::LoadCursor(NULL, IDC_SIZEALL),
- ::LoadCursor(NULL, IDC_IBEAM),
-
- ::LoadCursor(NULL, IDC_NO),
- ::LoadCursor(NULL, IDC_SIZEALL),
- ::LoadCursor(NULL, IDC_SIZENESW),
- ::LoadCursor(NULL, IDC_SIZENS),
- ::LoadCursor(NULL, IDC_SIZENWSE),
- ::LoadCursor(NULL, IDC_SIZEWE),
- ::LoadCursor(NULL, IDC_WAIT),
- NULL
- };
- ::SetCursor(cursors[mCursor]);
- }
- void WinBFWindow::SetClientPosition(int x, int y)
- {
- RECT rect;
- ::GetClientRect(mHWnd, &rect);
- ::OffsetRect(&rect, x, y);
- LONG aStyle = ::GetWindowLong(mHWnd, GWL_STYLE);
- LONG exStyle = ::GetWindowLong(mHWnd, GWL_EXSTYLE);
- ::AdjustWindowRectEx(&rect, aStyle, mMenu != NULL, exStyle);
- ::MoveWindow(mHWnd, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, FALSE);
- if (mMovedFunc != NULL)
- mMovedFunc(this);
- }
- void WinBFWindow::SetMouseVisible(bool isMouseVisible)
- {
- mMouseVisible = isMouseVisible;
- LONG aStyle = ::GetWindowLong(mHWnd, GWL_EXSTYLE);
- if (!isMouseVisible)
- aStyle |= WS_EX_TRANSPARENT;
- else
- aStyle &= ~WS_EX_TRANSPARENT;
- ::SetWindowLong(mHWnd, GWL_EXSTYLE, aStyle);
- }
- void WinBFWindow::SetAlpha(float alpha, uint32 destAlphaSrcMask, bool isMouseVisible)
- {
- if (destAlphaSrcMask != 0)
- {
- if (mAlphaMaskBitmap == NULL)
- {
- RECT clientRect;
- GetClientRect(mHWnd, &clientRect);
- RECT windowRect;
- GetWindowRect(mHWnd, &windowRect);
- int aWidth = clientRect.right - clientRect.left;
- int aHeight = clientRect.bottom - clientRect.top;
- mAlphaMaskWidth = aWidth;
- mAlphaMaskHeight = aHeight;
- mAlphaMaskDC = CreateCompatibleDC(NULL);
- BITMAPINFO bi = {};
- bi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
- bi.bmiHeader.biBitCount = 32;
- bi.bmiHeader.biWidth = aWidth;
- bi.bmiHeader.biHeight = -aHeight;
- bi.bmiHeader.biCompression = BI_RGB;
- bi.bmiHeader.biPlanes = 1;
- mAlphaMaskBitmap = CreateDIBSection(mAlphaMaskDC, &bi,
- DIB_RGB_COLORS, (void**)&mAlphaMaskPixels, NULL, 0);
- GdiFlush();
- }
- HDC hdc = GetDC(mHWnd);
- if (hdc)
- {
- DXRenderWindow* renderWindow = (DXRenderWindow*) mRenderWindow;
- renderWindow->CopyBitsTo(mAlphaMaskPixels, mAlphaMaskWidth, mAlphaMaskHeight);
- //for (int i = 0; i < mAlphaMaskWidth*mAlphaMaskHeight/2; i++)
- //mAlphaMaskPixels[i] = 0x80FF8000;
-
- HGDIOBJ hPrevObj = 0;
- POINT ptDest = {0, 0};
- POINT ptSrc = {0, 0};
- SIZE client = {mAlphaMaskWidth, mAlphaMaskHeight};
- BLENDFUNCTION blendFunc = {AC_SRC_OVER, 0, 255, AC_SRC_ALPHA};
- hPrevObj = SelectObject(mAlphaMaskDC, mAlphaMaskBitmap);
- ClientToScreen(mHWnd, &ptDest);
-
- BOOL worked = ::UpdateLayeredWindow(mHWnd, hdc, NULL, &client,
- mAlphaMaskDC, &ptSrc, 0, &blendFunc, ULW_ALPHA);
- DWORD error = GetLastError();
- SelectObject(mAlphaMaskDC, hPrevObj);
- ReleaseDC(mHWnd, hdc);
- }
- }
- else
- {
- ::SetLayeredWindowAttributes(mHWnd, 0, (int) (alpha * 255), LWA_ALPHA);
- }
- SetMouseVisible(isMouseVisible);
- }
- void WinBFWindow::CaptureMouse()
- {
- //OutputDebugStrF("CaptureMouse() Capture HWnd: %X\n", mHWnd);
- ::SetCapture(mHWnd);
-
- for (auto window : gBFApp->mWindowList)
- {
- if (window == this)
- continue;
- for (int i = 0; i < MOUSEBUTTON_MAX; i++)
- {
- if (window->mIsMouseDown[i])
- {
- window->mMouseUpFunc(window, -1, -1, i);
- window->mIsMouseDown[i] = false;
- }
- }
- }
- }
- bool WinBFWindow::IsMouseCaptured()
- {
- return (mHWnd != NULL) && (GetCapture() == mHWnd);
- }
- uint32 WinBFApp::GetClipboardFormat(const StringImpl& format)
- {
- if (format == "text")
- return CF_UNICODETEXT;
- else if (format == "atext")
- return CF_TEXT;
- // StringToUIntMap::iterator itr = mClipboardFormatMap.find(format);
- // if (itr != mClipboardFormatMap.end())
- // return itr->second;
- uint32 aFormat;
- if (mClipboardFormatMap.TryGetValue(format, &aFormat))
- return aFormat;
- String sysFormatName = "BF_" + format;
- aFormat = ::RegisterClipboardFormatA(sysFormatName.c_str());
- mClipboardFormatMap[sysFormatName] = aFormat;
- return aFormat;
- }
- void* WinBFApp::GetClipboardData(const StringImpl& format, int* size)
- {
- HWND aWindow = NULL;
- if (!mWindowList.empty())
- aWindow = ((WinBFWindow*) mWindowList.front())->mHWnd;
- uint32 aFormat = GetClipboardFormat(format);
- if (aFormat != 0)
- {
- if (OpenClipboard(aWindow))
- {
- HGLOBAL globalHandle = ::GetClipboardData(aFormat);
- if (globalHandle == NULL)
- {
- if (format == "text")
- {
- int aSize = 0;
- char* charPtr = (char*) GetClipboardData("atext", &aSize);
- if (charPtr == NULL)
- return NULL;
-
- *size = (int)::GlobalSize(globalHandle);
- void* aPtr = ::GlobalLock(globalHandle);
-
- mLockedHGlobalMap[aPtr] = globalHandle;
-
- CloseClipboard();
- return aPtr;
- }
- CloseClipboard();
- *size = 0;
- return NULL;
- }
- *size = (int)::GlobalSize(globalHandle);
- void* aPtr = ::GlobalLock(globalHandle);
- static String utf8String;
- utf8String = UTF8Encode((WCHAR*)aPtr);
- ::GlobalUnlock(globalHandle);
- CloseClipboard();
- return (void*)utf8String.c_str();
- }
- }
-
- *size = 0;
- return NULL;
- }
- void WinBFApp::ReleaseClipboardData(void* ptr)
- {
- HGLOBAL globalHandle;
- if (mLockedHGlobalMap.Remove(ptr, &globalHandle))
- {
- ::GlobalUnlock(globalHandle);
- }
- }
- void WinBFApp::SetClipboardData(const StringImpl& format, const void* ptr, int size, bool resetClipboard)
- {
- BP_ZONE("WinBFApp::SetClipboardData");
- HWND aWindow = NULL;
- if (!mWindowList.empty())
- aWindow = ((WinBFWindow*) mWindowList.front())->mHWnd;
- uint32 aFormat = GetClipboardFormat(format);
-
- if (aFormat != 0)
- {
- if (OpenClipboard(aWindow))
- {
- if (resetClipboard)
- {
- BP_ZONE("WinBFApp::SetClipboardData:empty");
- EmptyClipboard();
- }
-
- if (format == "text")
- {
- BP_ZONE("WinBFApp::SetClipboardData:text");
- HGLOBAL globalHandle = GlobalAlloc(GMEM_MOVEABLE | GMEM_DDESHARE, size * 2);
- char* data = (char*)GlobalLock(globalHandle);
- UTF16String wString;
- //
- {
- BP_ZONE("WinBFApp::SetClipboardData:utf8decode");
- wString = UTF8Decode((char*)ptr);
- }
- memcpy(data, wString.c_str(), size * 2);
- GlobalUnlock(globalHandle);
- ::SetClipboardData(CF_UNICODETEXT, globalHandle);
- }
- else if (format == "atext")
- {
- HGLOBAL globalHandle = GlobalAlloc(GMEM_MOVEABLE | GMEM_DDESHARE, size);
- char* data = (char*)GlobalLock(globalHandle);
- memcpy(data, ptr, size);
- GlobalUnlock(globalHandle);
- ::SetClipboardData(CF_TEXT, globalHandle);
- }
-
- CloseClipboard();
- }
- }
- /*if (format == "text")
- {
- //String aString = ToString((const WCHAR*) ptr);
- String aString = (const char*)ptr;
- SetClipboardData("atext", aString.c_str(), (int)aString.length() + 1, false);
- }*/
- }
- BFMenu* WinBFWindow::AddMenuItem(BFMenu* parent, int insertIdx, const char* text, const char* hotKey, BFSysBitmap* sysBitmap, bool enabled, int checkState, bool radioCheck)
- {
- UTF16String lText;
- if (text != NULL)
- lText = UTF8Decode(text);
- UTF16String lHotKey;
- if (hotKey != NULL)
- lHotKey = UTF8Decode(hotKey);
- bool wasEmpty = mMenu->mBFMenuList.size() == 0;
-
- if (parent == NULL)
- parent = mMenu;
- if ((parent->mBFMenuList.size() == 1) && (((WinBFMenu*) parent->mBFMenuList.front())->mIsPlaceholder))
- {
- // Get rid of placeholder menu item
- auto placeholderMenuItem = parent->mBFMenuList.front();
- RemoveMenuItem(placeholderMenuItem);
- delete placeholderMenuItem;
- }
-
- WinBFMenu* winBFMenuParent = (WinBFMenu*) parent;
- WinBFMenu* newMenu = new WinBFMenu();
- newMenu->mMenuId = ++WinBFMenu::mMenuCount;
- newMenu->mParent = parent;
- //static int allocIdx = 0;
- //allocIdx++;
- //OutputDebugStrF("MenuIdx %d %@\n", allocIdx, newMenu);
- if ((winBFMenuParent != NULL) && (winBFMenuParent->mMenu == NULL))
- {
- winBFMenuParent->mMenu = ::CreateMenu();
- mHMenuMap[winBFMenuParent->mMenu] = winBFMenuParent;
- MENUITEMINFO menuItem;
- memset(&menuItem, 0, sizeof(MENUITEMINFO));
- menuItem.cbSize = sizeof(MENUITEMINFO);
- menuItem.fMask = MIIM_SUBMENU;
- menuItem.hSubMenu = winBFMenuParent->mMenu;
-
- ::SetMenuItemInfo(((WinBFMenu*) winBFMenuParent->mParent)->mMenu, winBFMenuParent->mMenuId, FALSE, &menuItem);
- }
- mMenuIDMap[newMenu->mMenuId] = newMenu;
- BF_ASSERT(insertIdx <= (int) parent->mBFMenuList.size());
-
- ////
- UTF16String lCombinedName;
- MENUITEMINFOW menuItem;
- memset(&menuItem, 0, sizeof(MENUITEMINFO));
- menuItem.cbSize = sizeof(MENUITEMINFO);
- menuItem.fMask = MIIM_FTYPE | MIIM_ID;
- if (text != NULL)
- {
- menuItem.fMask |= MIIM_STRING;
- menuItem.fType = MFT_STRING;
- }
- else
- menuItem.fType = MFT_SEPARATOR;
- menuItem.fState = enabled ? MFS_DEFAULT : MFS_GRAYED;
- if (checkState == 0)
- menuItem.fState |= MFS_UNCHECKED;
- if (checkState == 1)
- menuItem.fState |= MFS_CHECKED;
- if (radioCheck)
- menuItem.fType = MFT_RADIOCHECK;
-
- menuItem.wID = newMenu->mMenuId;
- if (text != NULL)
- {
- menuItem.dwTypeData = (WCHAR*)lText.c_str();
- }
- if (hotKey != NULL)
- {
- String combinedName = String(text);
- combinedName += "\t";
- if (hotKey[0] == '#')
- {
- combinedName += hotKey + 1;
- }
- else
- {
- combinedName += hotKey;
- newMenu->ParseHotKey(hotKey);
- }
- lCombinedName = UTF8Decode(combinedName);
- menuItem.dwTypeData = (WCHAR*)lCombinedName.c_str();
- }
- ::InsertMenuItemW(winBFMenuParent->mMenu, insertIdx, TRUE, &menuItem);
- ////////
- /*MENUITEMINFO menuItem;
- memset(&menuItem, 0, sizeof(MENUITEMINFO));
- menuItem.cbSize = sizeof(MENUITEMINFO);
- menuItem.fMask = MIIM_ID;
- menuItem.wID = newMenu->mMenuId;
- ::InsertMenuItem(winBFMenuParent->mMenu, insertIdx, TRUE, &menuItem);*/
- ModifyMenuItem(newMenu, text, hotKey, sysBitmap, enabled, checkState, radioCheck);
- parent->mBFMenuList.push_back(newMenu);
- return newMenu;
- }
- void WinBFWindow::ModifyMenuItem(BFMenu* item, const char* text, const char* hotKey, BFSysBitmap* sysBitmap, bool enabled, int checkState, bool radioCheck)
- {
- UTF16String lText;
- if (text != NULL)
- lText = UTF8Decode(text);
- UTF16String lHotKey;
- if (hotKey != NULL)
- lHotKey = UTF8Decode(hotKey);
- WinBFMenu* aMenu = (WinBFMenu*)item;
- WinBFMenu* parentMenu = (WinBFMenu*) item->mParent;
- UTF16String lCombinedName;
-
- MENUITEMINFOW menuItem;
- memset(&menuItem, 0, sizeof(MENUITEMINFO));
- menuItem.cbSize = sizeof(MENUITEMINFO);
- menuItem.fMask = MIIM_FTYPE | MIIM_ID;
- ::GetMenuItemInfoW(parentMenu->mMenu, aMenu->mMenuId, FALSE, &menuItem);
- menuItem.fMask |= MIIM_STATE;
- if (text != NULL)
- {
- menuItem.fMask |= MIIM_STRING;
- //menuItem.fType = MFT_STRING;
- }
- /*else
- menuItem.fType = MFT_SEPARATOR;*/
- menuItem.fState = enabled ? /*MFS_DEFAULT*/0 : MFS_GRAYED;
- if (checkState != -1)
- {
- menuItem.fMask |= MIIM_CHECKMARKS;
- }
- if (checkState == 0)
- menuItem.fState |= MFS_UNCHECKED;
- if (checkState == 1)
- menuItem.fState |= MFS_CHECKED;
- if (radioCheck)
- menuItem.fType = MFT_RADIOCHECK;
- menuItem.wID = aMenu->mMenuId;
- menuItem.dwTypeData = (WCHAR*)lText.c_str();
- if (hotKey != NULL)
- {
- menuItem.fMask |= MIIM_DATA;
-
- String combinedName = String(text);
- combinedName += "\t";
- if (hotKey[0] == '#')
- {
- combinedName += hotKey + 1;
- }
- else
- {
- combinedName += hotKey;
- aMenu->ParseHotKey(hotKey);
- }
- lCombinedName = UTF8Decode(combinedName);
- menuItem.dwTypeData = (WCHAR*)lCombinedName.c_str();
- }
- ::SetMenuItemInfoW(parentMenu->mMenu, aMenu->mMenuId, FALSE, &menuItem);
- }
- void WinBFWindow::RemoveMenuItem(BFMenu* item)
- {
- WinBFMenu* aMenu = (WinBFMenu*) item;
- WinBFMenu* parentMenu = (WinBFMenu*) item->mParent;
- //auto itr = mMenuIDMap.find(aMenu->mMenuId);
- //mMenuIDMap.erase(itr);
- mMenuIDMap.Remove(aMenu->mMenuId);
- ::RemoveMenu(parentMenu->mMenu, aMenu->mMenuId, MF_BYCOMMAND);
- }
- BFSysBitmap* WinBFApp::LoadSysBitmap(const WCHAR* fileName)
- {
- return NULL;
- }
- BFSoundManager* WinBFApp::GetSoundManager()
- {
- if (mDSoundManager == NULL)
- mDSoundManager = new DSoundManager(NULL);
- return mDSoundManager;
- }
- void WinBFWindow::ModalsRemoved()
- {
- ::EnableWindow(mHWnd, TRUE);
- if (mChildren.empty())
- ::SetFocus(mHWnd);
- }
- DrawLayer* WinBFApp::CreateDrawLayer(BFWindow* window)
- {
- DXDrawLayer* drawLayer = new DXDrawLayer();
- if (window != NULL)
- {
- drawLayer->mRenderWindow = window->mRenderWindow;
- window->mRenderWindow->mDrawLayerList.push_back(drawLayer);
- }
- drawLayer->mRenderDevice = mRenderDevice;
- return drawLayer;
- }
|