12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138 |
- #include <dsound.h>
- #include "WinBFApp.h"
- #include "DXRenderDevice.h"
- #include <signal.h>
- #include "../../util/BeefPerf.h"
- #include "DSoundManager.h"
- #include "DInputManager.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;
- }
- struct AdjustedMonRect
- {
- int mMonCount;
- int mX;
- int mY;
- int mWidth;
- int mHeight;
- };
- static BOOL ClipToMonitor(HMONITOR mon, HDC hdc, LPRECT monRect, LPARAM userArg)
- {
- AdjustedMonRect* outRect = (AdjustedMonRect*)userArg;
-
- MONITORINFO monitorInfo = { sizeof(MONITORINFO) };
- if (::GetMonitorInfo(mon, &monitorInfo) == 0)
- return TRUE;
- outRect->mMonCount++;
-
- if (outRect->mX < monitorInfo.rcWork.left)
- outRect->mX = monitorInfo.rcWork.left;
- else if (outRect->mX + outRect->mWidth >= monitorInfo.rcWork.right)
- outRect->mX = BF_MAX((int)monitorInfo.rcWork.left, monitorInfo.rcWork.right - outRect->mWidth);
-
- if (outRect->mY < monitorInfo.rcWork.top)
- outRect->mY = monitorInfo.rcWork.top;
- else if (outRect->mY + outRect->mHeight >= monitorInfo.rcWork.bottom)
- outRect->mY = BF_MAX((int)monitorInfo.rcWork.top, monitorInfo.rcWork.bottom - outRect->mHeight);
-
- return TRUE;
- }
- static BOOL KeyboardLayoutHasAltGr(HKL layout)
- {
- BOOL hasAltGr = FALSE;
- int scancode;
- for (WORD i = 32; i < 256; ++i)
- {
- scancode = VkKeyScanEx((TCHAR)i, layout);
- if ((scancode != -1) && ((scancode & 0x600) == 0x600))
- {
- hasAltGr = TRUE;
- break;
- }
- }
- return hasAltGr;
- }
- WinBFWindow::WinBFWindow(BFWindow* parent, const StringImpl& title, int x, int y, int width, int height, int windowFlags)
- {
- //OutputDebugStrF("Wnd %p Create\n", this);
- HINSTANCE hInstance = GetModuleHandle(NULL);
-
- mMinWidth = 128;
- mMinHeight = 128;
- WNDCLASSW wc;
- wc.style = 0;
- 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_ACCEPTFILES))
- windowFlagsEx |= WS_EX_ACCEPTFILES;
- 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)
- {
- AdjustedMonRect adjustRect = { 0, x, y, width, height };
- RECT wantRect = { x, y, x + width, y + height };
- EnumDisplayMonitors(NULL, &wantRect, ClipToMonitor, (LPARAM)&adjustRect);
- if (adjustRect.mMonCount == 0)
- EnumDisplayMonitors(NULL, NULL, ClipToMonitor, (LPARAM)&adjustRect);
- x = adjustRect.mX;
- y = adjustRect.mY;
- width = adjustRect.mWidth;
- height = adjustRect.mHeight;
- }
-
- 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;
- // if (windowFlags & BFWINDOW_SHOWMINIMIZED)
- // showFlags = SWP_
- 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;
- }
- if (windowFlags & (BFWINDOW_SHOWMINIMIZED | BFWINDOW_SHOWMAXIMIZED))
- {
- WINDOWPLACEMENT wndPlacement = { sizeof(WINDOWPLACEMENT), 0 };
- ::GetWindowPlacement(mHWnd, &wndPlacement);
- if (windowFlags & BFWINDOW_SHOWMINIMIZED)
- wndPlacement.showCmd = SW_SHOWMINIMIZED;
- else if (windowFlags & BFWINDOW_SHOWMAXIMIZED)
- wndPlacement.showCmd = SW_SHOWMAXIMIZED;
- else
- wndPlacement.showCmd = SW_SHOWNORMAL;
- wndPlacement.rcNormalPosition.left = x;
- wndPlacement.rcNormalPosition.top = y;
- wndPlacement.rcNormalPosition.right = x + width;
- wndPlacement.rcNormalPosition.bottom = y + height;
- ::SetWindowPlacement(mHWnd, &wndPlacement);
- }
- else
- {
- SetWindowPos(mHWnd, relativeWindow, x, y, width, height, showFlags);
- }
-
- SetTimer(mHWnd, 0, 10, NULL);
-
- mIsMouseInside = false;
- mRenderWindow = new DXRenderWindow((DXRenderDevice*) gBFApp->mRenderDevice, this, (windowFlags & BFWINDOW_FULLSCREEN) == 0);
- 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;
- mAwaitKeyReleases = false;
- mAwaitKeyReleasesEventTick = 0;
- mAwaitKeyReleasesCheckIdx = 0;
- mFocusLostTick = ::GetTickCount();
- 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);
- }
- HKL layout = GetKeyboardLayout(0);
- mKeyLayoutHasAltGr = (KeyboardLayoutHasAltGr(layout) == TRUE);
- }
- WinBFWindow::~WinBFWindow()
- {
- //OutputDebugStrF("Wnd %p Destroyed\n", this);
- 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)
- {
- ///OutputDebugStrF("Lost focus\n");
- mFocusLostTick = ::GetTickCount();
- 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::GotFocus()
- {
- DWORD tickNow = ::GetTickCount();
- //OutputDebugStrF("GotFocus since lost %d\n", tickNow - mFocusLostTick);
- if (tickNow - mFocusLostTick >= 1000)
- {
- mAwaitKeyReleases = true;
- mAwaitKeyReleasesCheckIdx = 0;
- mAwaitKeyReleasesEventTick = ::GetTickCount();
- }
- }
- void WinBFWindow::SetForeground()
- {
- bool hadFocus = mHasFocus;
- DWORD prevFocusLostTick = mFocusLostTick;
- if (mFlags & BFWINDOW_FAKEFOCUS)
- {
- mHasFocus = true;
- mSoftHasFocus = true;
- return;
- }
- ::SetFocus(mHWnd);
- ::SetForegroundWindow(mHWnd);
-
- //OutputDebugStrF("SetForeground %p %d %d %d\n", mHWnd, hadFocus, ::GetTickCount() - prevFocusLostTick, mAwaitKeyReleases);
- }
- 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);
- }
- }
- bool WinBFWindow::CheckKeyReleases(bool isKeyDown)
- {
- if (!mHasFocus)
- GotFocus();
- if (!mAwaitKeyReleases)
- return true;
- // Time expired with no key presses
- if ((mAwaitKeyReleasesEventTick != 0) && (mAwaitKeyReleasesCheckIdx == 0) && (::GetTickCount() - mAwaitKeyReleasesEventTick > 150))
- {
- //OutputDebugStrF("CheckKeyReleases no initial key press\n");
- mAwaitKeyReleases = false;
- return true;
- }
- mAwaitKeyReleasesCheckIdx++;
- bool hasKeyDown = false;
- uint8 keysDown[256] = { 0 };
- ::GetKeyboardState((PBYTE)&keysDown);
- for (int i = 1; i < 256; i++)
- if (keysDown[i] & 0x80)
- hasKeyDown = true;
- if ((hasKeyDown) && (::GetTickCount() - mAwaitKeyReleasesEventTick >= 600))
- {
- // String dbgStr = "CheckKeyReleases timeout. Keys down:";
- // for (int i = 1; i < 256; i++)
- // if (keysDown[i] & 0x80)
- // dbgStr += StrFormat(" %2X", i);
- // dbgStr += "\n";
- // OutputDebugStr(dbgStr);
- hasKeyDown = false;
- }
- if (!hasKeyDown)
- {
- mAwaitKeyReleases = false;
- mAwaitKeyReleasesCheckIdx = 0;
- mAwaitKeyReleasesEventTick = 0;
- }
- return !mAwaitKeyReleases;
- }
- 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("Wnd %p mNeedsStateReset MouseUp %d\n", this, i);
- }
- }
- //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_DISPLAYCHANGE:
- ((DXRenderWindow*)mRenderWindow)->mRefreshRate = 0;
- break;
- 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_XBUTTONDOWN:
- case WM_LBUTTONDBLCLK:
- case WM_RBUTTONDBLCLK:
- case WM_LBUTTONUP:
- case WM_RBUTTONUP:
- case WM_MBUTTONUP:
- case WM_XBUTTONUP:
- case WM_MOUSEWHEEL:
- case WM_MOUSEHWHEEL:
- case WM_MOUSEMOVE:
- {
- int x = (short)LOWORD(lParam);
- int y = (short)HIWORD(lParam);
- bool releaseCapture = false;
- POINT point = {x, y};
- if ((uMsg != WM_MOUSEWHEEL) && (uMsg != WM_MOUSEHWHEEL))
- ::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;
- auto _BtnDown = [&](int btn)
- {
- BF_ASSERT(btn < MOUSEBUTTON_MAX);
- if (btn >= MOUSEBUTTON_MAX)
- return;
- //OutputDebugStrF("Wnd %p BtnDown %d\n", this, btn);
- DWORD tickNow = BFTickCount();
- if (::SetCapture(hWnd) != hWnd)
- {
- // Not captured, no buttons were down
- for (int i = 0; i < MOUSEBUTTON_MAX; i++)
- {
- if (mIsMouseDown[i])
- {
- mMouseUpFunc(this, x, y, i);
- mIsMouseDown[i] = false;
- //OutputDebugStrF("Wnd %p BtnDown MouseUp %d\n", this, i);
- }
- }
- }
- mIsMouseDown[btn] = true;
- BFCoord mouseCoords = { x, y };
- if ((mouseCoords.mX != mMouseDownCoords[btn].mX) || (mouseCoords.mY != mMouseDownCoords[btn].mY) ||
- (tickNow - mMouseDownTicks[btn] > ::GetDoubleClickTime()))
- mMouseClickCount[btn] = 0;
- mMouseDownCoords[btn] = mouseCoords;
- mMouseClickCount[btn]++;
- mMouseDownTicks[btn] = tickNow;
- mMouseDownFunc(this, x, y, btn, mMouseClickCount[btn]);
- };
- auto _BtnUp = [&](int btn)
- {
- BF_ASSERT(btn < MOUSEBUTTON_MAX);
- if (btn >= MOUSEBUTTON_MAX)
- return;
- //OutputDebugStrF("Wnd %p BtnUp %d\n", this, btn);
- releaseCapture = true;
- mIsMouseDown[btn] = false;
- mMouseUpFunc(this, x, y, btn);
- };
- switch (uMsg)
- {
- case WM_LBUTTONDOWN:
- //OutputDebugStrF("WM_LBUTTONDOWN Capture HWnd: %X\n", hWnd);
- _BtnDown(0);
- break;
- case WM_RBUTTONDOWN:
- //OutputDebugStrF("WM_RBUTTONDOWN Capture HWnd: %X\n", hWnd);
- _BtnDown(1);
- break;
- case WM_MBUTTONDOWN:
- _BtnDown(2);
- break;
- case WM_XBUTTONDOWN:
- _BtnDown((int)(wParam >> 16) + 2);
- break;
- case WM_LBUTTONUP:
- _BtnUp(0);
- break;
- case WM_RBUTTONUP:
- _BtnUp(1);
- break;
- case WM_MBUTTONUP:
- _BtnUp(2);
- break;
- case WM_XBUTTONUP:
- _BtnUp((int)(wParam >> 16) + 2);
- break;
- case WM_MOUSEWHEEL:
- case WM_MOUSEHWHEEL:
- {
- 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;
- }
- }
- UINT ucNumLines = 0;
- SystemParametersInfo(SPI_GETWHEELSCROLLLINES, 0, &ucNumLines, 0);
- if (ucNumLines == 0)
- ucNumLines = 3; // Default
- if ((cursorWindow != this) && (mIsMouseInside))
- {
- mMouseLeaveFunc(this);
- mIsMouseInside = false;
- }
- POINT pt = {x, y};
- ScreenToClient(cursorWindow->mHWnd, &pt);
-
- if (uMsg == WM_MOUSEWHEEL)
- {
- float delta = ((int16)HIWORD(wParam)) / 120.0f * (float)ucNumLines;
- mMouseWheelFunc(cursorWindow, pt.x, pt.y, 0, delta);
- }
- else
- {
- float delta = ((int16)HIWORD(wParam)) / 120.0f;
- mMouseWheelFunc(cursorWindow, pt.x, pt.y, delta, 0);
- }
- }
- 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("Wnd %p Release Capture\n", this);
- //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);
- if (!mHasFocus)
- GotFocus();
- 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();
- }
- }*/
- //NOTE: This line broke Alt+Gr for braces and such. Determine why this was needed.
- //if ((!mIsKeyDown[VK_MENU]) && (!mIsKeyDown[VK_CONTROL]))
- if (CheckKeyReleases(true))
- {
- 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
- if ((mKeyLayoutHasAltGr) && (keyCode == VK_MENU) && ((lParam & 0x01000000) != 0))
- keyCode = VK_RMENU;
- mIsKeyDown[keyCode] = true;
-
- // if ((keyCode == 192) && (mIsKeyDown[VK_MENU]))
- // {
- // ((DXRenderDevice*)mRenderWindow->mRenderDevice)->mNeedsReinitNative = 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 ((CheckKeyReleases(true)) && (mKeyDownFunc(this, keyCode, (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]))
- {
- if (CheckKeyReleases(true))
- 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 ((mKeyLayoutHasAltGr) && (keyCode == VK_MENU) && ((lParam & 0x01000000) != 0))
- keyCode = VK_RMENU;
- if (mIsKeyDown[keyCode])
- {
- mKeyUpFunc(this, keyCode);
- mIsKeyDown[keyCode] = false;
- }
- CheckKeyReleases(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))
- {
- //OutputDebugStrF("Timer detected got focus %p\r\n", hWnd);
- GotFocus();
- mHasFocus = true;
- mSoftHasFocus = true;
- mGotFocusFunc(this);
- }
- 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;
- case WM_INPUTLANGCHANGE:
- mKeyLayoutHasAltGr = (KeyboardLayoutHasAltGr((HKL)lParam) == TRUE);
- break;
- case WM_DROPFILES:
- {
- HDROP hDropInfo = (HDROP)wParam;
- char sItem[MAX_PATH];
-
- for(int i = 0; DragQueryFileA(hDropInfo, i, (LPSTR)sItem, sizeof(sItem)); i++)
- mDragDropFileFunc(this, sItem);
- DragFinish(hDropInfo);
- }
- 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;
- typedef UINT(NTAPI *GetDpiForWindow_t)(HWND);
- static GetDpiForWindow_t gGetDpiForWindow = NULL;
- static HMODULE gUserDll = NULL;
- WinBFApp::WinBFApp()
- {
- #ifndef BF_MINGW
- //_CrtSetReportHook(WinBFReportHook);
- #endif
- if (gUserDll == NULL)
- {
- gUserDll = ::LoadLibraryA("user32.dll");
- gGetDpiForWindow = (GetDpiForWindow_t)::GetProcAddress(gUserDll, "GetDpiForWindow");
- }
- 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;
- mDInputManager = NULL;
- mVSyncThreadId = 0;
- mClosing = false;
- mVSyncActive = false;
- mVSyncThread = BfpThread_Create(VSyncThreadProcThunk, (void*)this, 128 * 1024, BfpThreadCreateFlag_StackSizeReserve, &mVSyncThreadId);
- BfpThread_SetPriority(mVSyncThread, BfpThreadPriority_High, NULL);
- }
- void BFP_CALLTYPE WinBFApp::VSyncThreadProcThunk(void* ptr)
- {
- ((WinBFApp*)ptr)->VSyncThreadProc();
- }
- void WinBFApp::VSyncThreadProc()
- {
- while (!mClosing)
- {
- bool didWait = false;
- IDXGIOutput* output = NULL;
- //
- {
- AutoCrit autoCrit(mCritSect);
- if ((mRenderDevice != NULL) && (!mRenderDevice->mRenderWindowList.IsEmpty()))
- {
- auto renderWindow = (DXRenderWindow*)mRenderDevice->mRenderWindowList[0];
- renderWindow->mDXSwapChain->GetContainingOutput(&output);
- }
- }
- if (output != NULL)
- {
- DWORD start = GetTickCount();
- bool success = output->WaitForVBlank() == 0;
- int elapsed = (int)(GetTickCount() - start);
- if (elapsed >= 20)
- {
- NOP;
- }
- if (success)
- {
- didWait = true;
- mVSyncActive = true;
- mVSyncEvent.Set();
- }
- output->Release();
- }
- if (!didWait)
- {
- mVSyncActive = false;
- BfpThread_Sleep(20);
- }
- }
- }
- WinBFApp::~WinBFApp()
- {
- mClosing = true;
- BfpThread_WaitFor(mVSyncThread, -1);
- BfpThread_Release(mVSyncThread);
- delete mRenderDevice;
- delete mDSoundManager;
- delete mDInputManager;
- }
- void WinBFApp::Init()
- {
- BP_ZONE("WinBFApp::Init");
- AutoCrit autoCrit(mCritSect);
- 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::Process()
- {
- BFApp::Process();
- auto dxRenderDevice = (DXRenderDevice*)mRenderDevice;
- if (dxRenderDevice->mNeedsReinitNative)
- {
- dxRenderDevice->mNeedsReinitNative = false;
- dxRenderDevice->ReinitNative();
- mForceNextDraw = true;
- }
- }
- void WinBFApp::Draw()
- {
- mRenderDevice->FrameStart();
- BFApp::Draw();
- mRenderDevice->FrameEnd();
- }
- void WinBFApp::GetDesktopResolution(int& width, int& height)
- {
- width = ::GetSystemMetrics(SM_CXSCREEN);
- height = ::GetSystemMetrics(SM_CYSCREEN);
- }
- static BOOL InflateRectToMonitor(HMONITOR mon, HDC hdc, LPRECT monRect, LPARAM userArg)
- {
- AdjustedMonRect* inflatedRect = (AdjustedMonRect*)userArg;
- MONITORINFO monitorInfo = { sizeof(MONITORINFO) };
- if (::GetMonitorInfo(mon, &monitorInfo) == 0)
- return TRUE;
- inflatedRect->mMonCount++;
- if (inflatedRect->mMonCount == 1)
- {
- inflatedRect->mX = monitorInfo.rcWork.left;
- inflatedRect->mY = monitorInfo.rcWork.top;
- inflatedRect->mWidth = monitorInfo.rcWork.right - monitorInfo.rcWork.left;
- inflatedRect->mHeight = monitorInfo.rcWork.bottom - monitorInfo.rcWork.top;
- }
- else
- {
- int minLeft = BF_MIN(inflatedRect->mX, monitorInfo.rcWork.left);
- int minTop = BF_MIN(inflatedRect->mY, monitorInfo.rcWork.top);
- int maxRight = BF_MAX(inflatedRect->mX + inflatedRect->mWidth, monitorInfo.rcWork.right);
- int maxBottom = BF_MAX(inflatedRect->mY + inflatedRect->mHeight, monitorInfo.rcWork.bottom);
- inflatedRect->mX = minLeft;
- inflatedRect->mY = minTop;
- inflatedRect->mWidth = maxRight - minLeft;
- inflatedRect->mHeight = maxBottom - minTop;
- }
- return TRUE;
- }
- void WinBFApp::GetWorkspaceRect(int& x, int& y, int& width, int& height)
- {
- AdjustedMonRect inflateRect = { 0 };
- EnumDisplayMonitors(NULL, NULL, InflateRectToMonitor, (LPARAM)&inflateRect);
- x = inflateRect.mX;
- y = inflateRect.mY;
- width = inflateRect.mWidth;
- height = inflateRect.mHeight;
- }
- void WinBFApp::GetWorkspaceRectFrom(int fromX, int fromY, int fromWidth, int fromHeight, int & outX, int & outY, int & outWidth, int & outHeight)
- {
- AdjustedMonRect inflateRect = { 0 };
- RECT wantRect;
- wantRect.left = fromX;
- wantRect.top = fromY;
- wantRect.right = fromX + BF_MAX(fromWidth, 1);
- wantRect.bottom = fromY + BF_MAX(fromHeight, 1);
- EnumDisplayMonitors(NULL, &wantRect, InflateRectToMonitor, (LPARAM)&inflateRect);
- if (inflateRect.mMonCount == 0)
- {
- GetWorkspaceRect(outX, outY, outWidth, outHeight);
- return;
- }
- outX = inflateRect.mX;
- outY = inflateRect.mY;
- outWidth = inflateRect.mWidth;
- outHeight = inflateRect.mHeight;
- }
- BFWindow* WinBFApp::CreateNewWindow(BFWindow* parent, const StringImpl& title, int x, int y, int width, int height, int windowFlags)
- {
- AutoCrit autoCrit(mCritSect);
- 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);
- }
- }
- String WinBFApp::EnumerateInputDevices()
- {
- if (mDInputManager == NULL)
- mDInputManager = new DInputManager();
- return mDInputManager->EnumerateDevices();
- }
- BFInputDevice* WinBFApp::CreateInputDevice(const StringImpl& guid)
- {
- if (mDInputManager == NULL)
- mDInputManager = new DInputManager();
- return mDInputManager->CreateInputDevice(guid);
- }
- 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::GetPlacement(int* normX, int* normY, int* normWidth, int* normHeight, int* showKind)
- {
- WINDOWPLACEMENT wndPlacement = { sizeof(WINDOWPLACEMENT), 0 };
- ::GetWindowPlacement(mHWnd, &wndPlacement);
- *normX = wndPlacement.rcNormalPosition.left;
- *normY = wndPlacement.rcNormalPosition.top;
- *normWidth = wndPlacement.rcNormalPosition.right - wndPlacement.rcNormalPosition.left;
- *normHeight = wndPlacement.rcNormalPosition.bottom - wndPlacement.rcNormalPosition.top;
- switch (wndPlacement.showCmd)
- {
- case SW_SHOWMINIMIZED:
- *showKind = 1;
- break;
- case SW_SHOWMAXIMIZED:
- *showKind = 2;
- break;
- default:
- *showKind = 0;
- break;
- }
- }
- void WinBFWindow::Resize(int x, int y, int width, int height, int showKind)
- {
- WINDOWPLACEMENT wndPlacement = { sizeof(WINDOWPLACEMENT), 0 };
- ::GetWindowPlacement(mHWnd, &wndPlacement);
-
- switch (showKind)
- {
- case 1:
- wndPlacement.showCmd = SW_SHOWMINIMIZED;
- break;
- case 2:
- wndPlacement.showCmd = SW_SHOWMAXIMIZED;
- break;
- case 3:
- wndPlacement.showCmd = SW_SHOWNORMAL;
- break;
- }
- wndPlacement.rcNormalPosition.left = x;
- wndPlacement.rcNormalPosition.top = y;
- wndPlacement.rcNormalPosition.right = x + width;
- wndPlacement.rcNormalPosition.bottom = y + height;
- ::SetWindowPlacement(mHWnd, &wndPlacement);
- //::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("Wnd %p CaptureMouse", this);
- ::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);
- }
- int WinBFWindow::GetDPI()
- {
- if (gGetDpiForWindow != NULL)
- return (int)gGetDpiForWindow(mHWnd);
- return 96; // Default DPI
- }
- uint32 WinBFApp::GetClipboardFormat(const StringImpl& format)
- {
- if (format == "text")
- return CF_UNICODETEXT;
- else if (format == "atext")
- return CF_TEXT;
- uint32 aFormat;
- if (mClipboardFormatMap.TryGetValue(format, &aFormat))
- return aFormat;
-
- aFormat = ::RegisterClipboardFormatA(format.c_str());
- mClipboardFormatMap[format] = aFormat;
- return aFormat;
- }
- static String gClipboardData;
- 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 (aFormat == CF_UNICODETEXT)
- {
- CloseClipboard();
- // Return ascii text
- return (char*)GetClipboardData("atext", size);
- }
- CloseClipboard();
- *size = 0;
- return NULL;
- }
- *size = (int)::GlobalSize(globalHandle);
- void* aPtr = ::GlobalLock(globalHandle);
-
- if (aFormat == CF_UNICODETEXT)
- {
- gClipboardData = UTF8Encode((WCHAR*)aPtr);
- *size = (int)gClipboardData.length() + 1;
- }
- else
- {
- gClipboardData.Clear();
- gClipboardData.Insert(0, (char*)aPtr, *size);
- }
-
- ::GlobalUnlock(globalHandle);
- CloseClipboard();
- return (void*)gClipboardData.c_str();
- }
- }
- *size = 0;
- return NULL;
- }
- void WinBFApp::ReleaseClipboardData(void* ptr)
- {
-
- }
- 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
- {
- HGLOBAL globalHandle = GlobalAlloc(GMEM_MOVEABLE | GMEM_DDESHARE, size);
- char* data = (char*)GlobalLock(globalHandle);
- memcpy(data, ptr, size);
- GlobalUnlock(globalHandle);
- ::SetClipboardData(aFormat, globalHandle);
- }
-
- CloseClipboard();
- }
- }
- }
- 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;
- }
- intptr WinBFApp::GetCriticalThreadId(int idx)
- {
- if (idx == 0)
- return mVSyncThreadId;
- return 0;
- }
- 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;
- }
|