Example #1
0
HWND player_impl::create_window(const char *player_name)
{
	WNDCLASSEXA wcex;

	// 得到进程实例句柄.
	m_hinstance = (HINSTANCE)GetModuleHandle(NULL);
	// 创建非纯黑色的画刷, 用于ddraw播放时刷背景色.
	m_brbackground = CreateSolidBrush(RGB(0, 0, 1));
	wcex.cbSize = sizeof(WNDCLASSEXA);

	wcex.style			= CS_CLASSDC/*CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS*/;
	wcex.lpfnWndProc	= player_impl::static_win_wnd_proc;
	wcex.cbClsExtra	= 0;
	wcex.cbWndExtra	= 0;
	wcex.hInstance		= m_hinstance;
	wcex.hIcon			= LoadIcon(m_hinstance, MAKEINTRESOURCE(IDC_ICON));
	wcex.hCursor		= LoadCursor(NULL, IDC_ARROW);
	wcex.hbrBackground	= m_brbackground;	// (HBRUSH)(COLOR_WINDOW+1);
	wcex.lpszMenuName		= NULL;				// MAKEINTRESOURCE(IDC_AVPLAYER);
	wcex.lpszClassName	= player_name;
	wcex.hIconSm			= LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDC_ICON));

	if (!RegisterClassExA(&wcex))
	{
		::logger("register window class failed!\n");
		return NULL;
	}

	// 创建hook, 以便在窗口创建之前得到HWND句柄, 使HWND与this绑定.
	HHOOK hook = SetWindowsHookEx(WH_CBT, win_cbt_filter_hook, NULL, GetCurrentThreadId());
	win_cbt_context win_cbt_ctx;
	win_tls.set(&win_cbt_ctx);
	win_tls->hook = hook;
	win_tls->win = this;

	// 创建窗口.
	m_hwnd = CreateWindowExA(/*WS_EX_APPWINDOW*/0,
		player_name, player_name, WS_OVERLAPPEDWINDOW/* | WS_CLIPSIBLINGS | WS_CLIPCHILDREN*/,
		0, 0, 800, 600, NULL, NULL, m_hinstance, NULL);

	// 撤销hook.
	UnhookWindowsHookEx(hook);
	win_tls->hook = NULL;
	win_tls->win = NULL;

	ShowWindow(m_hwnd, SW_SHOW);

	return m_hwnd;
}
Example #2
0
static void register_testwindow_class(void)
{
    WNDCLASSEXA cls;

    ZeroMemory(&cls, sizeof(cls));
    cls.cbSize = sizeof(cls);
    cls.style = 0;
    cls.lpfnWndProc = testwindow_wndproc;
    cls.hInstance = NULL;
    cls.hCursor = LoadCursorA(0, (LPSTR)IDC_ARROW);
    cls.hbrBackground = (HBRUSH) COLOR_WINDOW;
    cls.lpszClassName = testwindow_class;

    RegisterClassExA(&cls);
}
Example #3
0
File: imm32.c Project: krofna/wine
static BOOL init(void) {
    WNDCLASSEX wc;
    HIMC imc;
    HMODULE hmod,huser;

    hmod = GetModuleHandleA("imm32.dll");
    huser = GetModuleHandleA("user32");
    pImmAssociateContextEx = (void*)GetProcAddress(hmod, "ImmAssociateContextEx");
    pImmIsUIMessageA = (void*)GetProcAddress(hmod, "ImmIsUIMessageA");
    pSendInput = (void*)GetProcAddress(huser, "SendInput");

    wc.cbSize        = sizeof(WNDCLASSEX);
    wc.style         = 0;
    wc.lpfnWndProc   = wndProc;
    wc.cbClsExtra    = 0;
    wc.cbWndExtra    = 0;
    wc.hInstance     = GetModuleHandle(0);
    wc.hIcon         = LoadIcon(NULL, IDI_APPLICATION);
    wc.hCursor       = LoadCursor(NULL, IDC_ARROW);
    wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
    wc.lpszMenuName  = NULL;
    wc.lpszClassName = wndcls;
    wc.hIconSm       = LoadIcon(NULL, IDI_APPLICATION);

    if (!RegisterClassExA(&wc))
        return FALSE;

    hwnd = CreateWindowEx(WS_EX_CLIENTEDGE, wndcls, "Wine imm32.dll test",
                          WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT,
                          240, 120, NULL, NULL, GetModuleHandle(0), NULL);
    if (!hwnd)
        return FALSE;

    imc = ImmGetContext(hwnd);
    if (!imc)
    {
        win_skip("IME support not implemented\n");
        return FALSE;
    }
    ImmReleaseContext(hwnd, imc);

    ShowWindow(hwnd, SW_SHOWNORMAL);
    UpdateWindow(hwnd);

    msg_spy_init(hwnd);

    return TRUE;
}
Example #4
0
//////////
//
// Creates the message window used for communicating actions
//
//////
	void iVjr_init_createMessageWindow(void)
	{
		ATOM			atom;
		WNDCLASSEXA		classa;


		//////////
		// Register the classes if need be
		//////
			while (1)
			{
				if (!GetClassInfoExA(ghInstance, (cs8*)cgcMessageWindowClass, &classa))
				{
					// Initialize
					memset(&classa, 0, sizeof(classa));

					// Populate
					classa.cbSize				= sizeof(WNDCLASSEXA);
					classa.hInstance			= ghInstance;
					classa.lpszClassName		= (cs8*)cgcMessageWindowClass;
					classa.lpfnWndProc			= &iWindow_wndProcMessage;

					// Register
					atom = RegisterClassExA(&classa);
					if (!atom)
						break;
				}



			//////////
			// Create the message window
			//////
				ghwndMsg = CreateWindowA((cs8*)cgcMessageWindowClass, (cs8*)cgcMessageWindowClass, 0, 0, 0, 0, 0, HWND_MESSAGE, null0, ghInstance, 0);
				if (ghwndMsg)
				{
					// Create a timer for the message window firing 20x per second
					SetTimer(ghwndMsg, 0, 50, null0);

					// Read events
					CreateThread(NULL, 0, &iReadEvents_messageWindow, 0, 0, 0);
					return;
				}
				break;
			}
			// We should never get here
			MessageBoxA(null0, "Error creating Visual FreePro Jr's message window.", "VJr - Fatal Error", MB_OK);
	}
Example #5
0
void
createDialog(void)
{
    STARTUPINFOA startinfo;
    WNDCLASSEXA WndClass;

    g_hInstance = GetModuleHandle(NULL);
    GetStartupInfoA(&startinfo);

    WndClass.cbSize        = sizeof WndClass;
    WndClass.style         = 0;
    WndClass.lpfnWndProc   = WndProc;
    WndClass.cbClsExtra    = 0;
    WndClass.cbWndExtra    = 0;
    WndClass.hInstance     = g_hInstance;
    WndClass.hIcon         = LoadIcon(g_hInstance, MAKEINTRESOURCE(IDI_MAINICON));
    WndClass.hCursor       = LoadCursor(NULL, IDC_ARROW);
    WndClass.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
    WndClass.lpszMenuName  = MAKEINTRESOURCEA(IDM_MAINMENU);
    WndClass.lpszClassName = "DrMingw";
    WndClass.hIconSm       = LoadIcon(g_hInstance, MAKEINTRESOURCE(IDI_MAINICON));

    if (!RegisterClassExA(&WndClass)) {
        ErrorMessageBox("RegisterClassEx: %s", LastErrorMessage());
        exit(EXIT_FAILURE);
    }

    g_hWnd = CreateWindowExA(
        WS_EX_CLIENTEDGE,
        WndClass.lpszClassName,
        "Dr. Mingw",
        WS_OVERLAPPEDWINDOW,
        CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
        NULL,
        NULL,
        g_hInstance,
        NULL
    );

    if (g_hWnd == NULL) {
        ErrorMessageBox("CreateWindowEx: %s", LastErrorMessage());
        exit(EXIT_FAILURE);
    }

    ShowWindow(g_hWnd, (startinfo.dwFlags & STARTF_USESHOWWINDOW) ? startinfo.wShowWindow : SW_SHOWDEFAULT);
    UpdateWindow(g_hWnd);
}
bool PlatformInit()
{
	g_window.need_quit = false;

	// Skip any upcoming error
	GetLastError();

	//	Some dual core systems have a problem where the different CPUs return different
	//	QueryPerformanceCounter values. So when this thread is schedule on the other CPU
	//	in a later frame, we could even get a negative frameTime. To solve this we force
	//	the main thread to always run on CPU 0.
	SetThreadAffinityMask(GetCurrentThread(), 1);

	// This is the way to change window icon manually:
	g_window.icon = LoadIcon(NULL, IDI_APPLICATION);
	if (g_window.icon == NULL)
	{
		MessageBox(HWND_DESKTOP, TEXT("Icon loading failed!"), TEXT("Error"), MB_OK | MB_ICONEXCLAMATION);
		return false;
	}

	g_window.instance = GetModuleHandle(NULL);

	// Register A Window Class
	WNDCLASSEXA window_class;
	ZeroMemory(&window_class, sizeof(WNDCLASSEX));
	window_class.cbSize = sizeof(WNDCLASSEX);
	window_class.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
	window_class.lpfnWndProc = (WNDPROC)(WindowProc);
	window_class.hInstance = g_window.instance;
	window_class.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
	window_class.hCursor = LoadCursor(NULL, IDC_ARROW);
	window_class.hIcon = g_window.icon;
	window_class.hIconSm = g_window.icon;
	window_class.lpszClassName = kApplicationClassName;
	if (RegisterClassExA(&window_class) == 0)
	{
		DestroyIcon(g_window.icon);
		MessageBox(HWND_DESKTOP, TEXT("RegisterClassEx Failed!"), TEXT("Error"), MB_OK | MB_ICONEXCLAMATION);
		return false;
	}

	AdjustVideoSettings();

	return true;
}
Example #7
0
static cairo_status_t
_wgl_dummy_ctx (cairo_wgl_context_t *ctx)
{
    WNDCLASSEXA wincl;
    PIXELFORMATDESCRIPTOR pfd;
    int format;
    HDC dc;

    ZeroMemory (&wincl, sizeof (WNDCLASSEXA));
    wincl.cbSize = sizeof (WNDCLASSEXA);
    wincl.hInstance = GetModuleHandle (0);
    wincl.lpszClassName = "cairo_wgl_context_dummy";
    wincl.lpfnWndProc = DefWindowProcA;
    wincl.style = CS_OWNDC;

    RegisterClassExA (&wincl);

    ctx->dummy_wnd = CreateWindowA ("cairo_wgl_context_dummy", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
    ctx->dummy_dc = GetDC (ctx->dummy_wnd);

    ZeroMemory (&pfd, sizeof (PIXELFORMATDESCRIPTOR));
    pfd.nSize = sizeof (PIXELFORMATDESCRIPTOR);
    pfd.nVersion = 1;
#ifndef WKC_CAIRO_CUSTOMIZE
    pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
    pfd.iPixelType = PFD_TYPE_RGBA;
    pfd.cColorBits = 24;
    pfd.cDepthBits = 16;
#else
    pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL;/* | PFD_DOUBLEBUFFER;*/
    pfd.iPixelType = PFD_TYPE_RGBA;
    pfd.cColorBits = 32;
    pfd.cDepthBits = 32;
    pfd.cStencilBits = 32;
#endif
    pfd.iLayerType = PFD_MAIN_PLANE;

    format = ChoosePixelFormat (ctx->dummy_dc, &pfd);
    SetPixelFormat (ctx->dummy_dc, format, &pfd);

    wglMakeCurrent(ctx->dummy_dc, ctx->rc);

    return CAIRO_STATUS_SUCCESS;
}
Example #8
0
ATOM MyRegisterClass(HINSTANCE hInstance)
{
	WNDCLASSEX wcex;

	wcex.cbSize = sizeof(WNDCLASSEX);
	wcex.style = NULL;
	wcex.lpfnWndProc = (WNDPROC)WndProc;
	wcex.cbClsExtra = 0;
	wcex.cbWndExtra = 0;
	wcex.hInstance = hInstance;
	wcex.hIcon = LoadIcon(NULL, IDI_SHIELD);
	wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
	wcex.hbrBackground = NULL;
	wcex.lpszMenuName = MAKEINTRESOURCE(IDR_MENU1);
	wcex.lpszClassName = szWindowClass;
	wcex.hIconSm = NULL;

	return RegisterClassExA(&wcex);
}
Example #9
0
void DX_Init(DWORD* table)
{
	WNDCLASSEXA wc = { sizeof(WNDCLASSEX), CS_CLASSDC, MsgProc, 0L, 0L, GetModuleHandleA(NULL), NULL, NULL, NULL, NULL, "DX", NULL };
	RegisterClassExA(&wc);
	HWND hWnd = CreateWindowA("DX", NULL, WS_OVERLAPPEDWINDOW, 100, 100, 300, 300, GetDesktopWindow(), NULL, wc.hInstance, NULL);
	LPDIRECT3D9 pD3D = Direct3DCreate9(D3D_SDK_VERSION);
	D3DPRESENT_PARAMETERS d3dpp;
	ZeroMemory(&d3dpp, sizeof(d3dpp));
	d3dpp.Windowed = TRUE;
	d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
	d3dpp.BackBufferFormat = D3DFMT_UNKNOWN;
	LPDIRECT3DDEVICE9 pd3dDevice;
	pD3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &pd3dDevice);
	DWORD* pVTable = (DWORD*)pd3dDevice;
	pVTable = (DWORD*)pVTable[0];
	table[0] = pVTable[42];
	table[1] = pVTable[82];
	DestroyWindow(hWnd);
}
Example #10
0
//Registers, creates, and shows the Window!!
bool WinCreate()
{
    WindowINST = GetModuleHandle(0); // Get current process handle
    std::string title = string_format("Cataclysm: Dark Days Ahead - %s", getVersionString());

    // Register window class
    WNDCLASSEXA WindowClassType   = WNDCLASSEXA();
    WindowClassType.cbSize        = sizeof(WNDCLASSEXA);
    WindowClassType.lpfnWndProc   = ProcessMessages;//the procedure that gets msgs
    WindowClassType.hInstance     = WindowINST;// hInstance
    WindowClassType.hIcon         = LoadIcon(WindowINST, MAKEINTRESOURCE(0)); // Get first resource
    WindowClassType.hIconSm       = LoadIcon(WindowINST, MAKEINTRESOURCE(0));
    WindowClassType.hCursor       = LoadCursor(NULL, IDC_ARROW);
    WindowClassType.lpszClassName = szWindowClass;
    if (!RegisterClassExA(&WindowClassType))
        return false;

    // Adjust window size
    uint32_t WndStyle = WS_CAPTION | WS_MINIMIZEBOX | WS_SYSMENU | WS_VISIBLE; // Basic window, show on creation
    RECT WndRect;
    WndRect.left   = WndRect.top = 0;
    WndRect.right  = WindowWidth;
    WndRect.bottom = WindowHeight;
    AdjustWindowRect(&WndRect, WndStyle, false);

    // Center window
    RECT WorkArea;
    SystemParametersInfo(SPI_GETWORKAREA, 0, &WorkArea, 0);
    int WindowX = WorkArea.right/2 - (WndRect.right - WndRect.left)/2;
    int WindowY = WorkArea.bottom/2 - (WndRect.bottom - WndRect.top)/2;

    // Magic
    WindowHandle = CreateWindowExA(0, szWindowClass , title.c_str(), WndStyle,
                                   WindowX, WindowY,
                                   WndRect.right - WndRect.left,
                                   WndRect.bottom - WndRect.top,
                                   0, 0, WindowINST, NULL);
    if (WindowHandle == 0)
        return false;

    return true;
};
Example #11
0
void
RegisterWindowClassA() 
{
	WNDCLASSEXA wcex;

	wcex.cbSize = sizeof(WNDCLASSEXA); 
	wcex.style			= CS_HREDRAW | CS_VREDRAW;
	wcex.lpfnWndProc	= WndProcA;
	wcex.cbClsExtra		= 0;
	wcex.cbWndExtra		= 0;
	wcex.hInstance		= hInstance;
	wcex.hIcon			= 0;
	wcex.hCursor		= 0;
	wcex.hbrBackground	= (HBRUSH)(COLOR_WINDOW + 1);
	wcex.lpszMenuName	= 0;
	wcex.lpszClassName	= "Azureus Window Hook";
	wcex.hIconSm		= 0;

	RegisterClassExA(&wcex);
}
Example #12
0
static
BOOL xxRegisterWndClasses(LPCSTR menuName)
{
    POCDEBUG_BREAK();
    CHAR buf[0x10] = { 0 };
    for (LONG i = 0; i < tmpTimes; i++)
    {
        WNDCLASSEXA Class = { 0 };
        sprintf(buf, "CLS_%d", i);
        Class.lpfnWndProc = DefWindowProcA;
        Class.lpszClassName = buf;
        Class.lpszMenuName = menuName;
        Class.cbSize = sizeof(WNDCLASSEXA);
        if (!RegisterClassExA(&Class))
        {
            return FALSE;
        }
    }
    return TRUE;
}
Example #13
0
ATOM WINAPI MyRegisterClass(HINSTANCE hInstance)
{
    WNDCLASSEX wcex;

    wcex.cbSize = sizeof(WNDCLASSEX);

    wcex.style			= 0;
    wcex.lpfnWndProc	= (WNDPROC)WndProc;
    wcex.cbClsExtra		= 0;
    wcex.cbWndExtra		= 0;
    wcex.hInstance		= hInstance;
    wcex.hIcon			= LoadIcon(NULL, IDI_APPLICATION);
    wcex.hCursor		= LoadCursor(NULL, IDC_ARROW);
    wcex.hbrBackground	= (HBRUSH)GetStockObject(WHITE_BRUSH);
    wcex.lpszMenuName	= NULL;
    wcex.lpszClassName	= szClassName;
    wcex.hIconSm        = NULL;

    return RegisterClassExA(&wcex);
}
Example #14
0
File: imm32.c Project: bilboed/wine
static int init(void) {
    WNDCLASSEX wc;
    HIMC imc;

    wc.cbSize        = sizeof(WNDCLASSEX);
    wc.style         = 0;
    wc.lpfnWndProc   = DefWindowProc;
    wc.cbClsExtra    = 0;
    wc.cbWndExtra    = 0;
    wc.hInstance     = GetModuleHandle(0);
    wc.hIcon         = LoadIcon(NULL, IDI_APPLICATION);
    wc.hCursor       = LoadCursor(NULL, IDC_ARROW);
    wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
    wc.lpszMenuName  = NULL;
    wc.lpszClassName = wndcls;
    wc.hIconSm       = LoadIcon(NULL, IDI_APPLICATION);

    if (!RegisterClassExA(&wc))
        return 0;

    hwnd = CreateWindowEx(WS_EX_CLIENTEDGE, wndcls, "Wine imm32.dll test",
                          WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT,
                          240, 120, NULL, NULL, GetModuleHandle(0), NULL);
    if (!hwnd)
        return 0;

    imc = ImmGetContext(hwnd);
    if (!imc)
    {
        win_skip("IME support not implemented\n");
        return 0;
    }
    ImmReleaseContext(hwnd, imc);

    ShowWindow(hwnd, SW_SHOWNORMAL);
    UpdateWindow(hwnd);

    msg_spy_init(hwnd);

    return 1;
}
Example #15
0
ATOM RegisterWinClass(const char* pszName,
					  WNDPROC proc,
					  HINSTANCE hInst,
					  UINT menuID,
					  UINT iconID,
					  UINT smallIconID)
{
	WNDCLASSEXA wc = {};
	wc.cbSize = sizeof(wc);

	wc.style		= CS_HREDRAW | CS_VREDRAW;
	wc.lpfnWndProc	= proc;
	wc.lpszClassName = pszName;
	wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
	wc.hCursor		= LoadCursor(NULL, IDC_ARROW);
	wc.hInstance	= hInst;
	wc.lpszMenuName	= MAKEINTRESOURCEA(menuID);
	wc.hIcon		= LoadIconA(hInst, MAKEINTRESOURCEA(iconID));
	wc.hIconSm		= LoadIconA(hInst, MAKEINTRESOURCEA(smallIconID));
	return RegisterClassExA(&wc);
}
Example #16
0
/***********************************************************************
 *           AtlModuleRegisterWndClassInfoA           [ATL.@]
 *
 * See AtlModuleRegisterWndClassInfoW.
 */
ATOM WINAPI AtlModuleRegisterWndClassInfoA(_ATL_MODULEA *pm, _ATL_WNDCLASSINFOA *wci, WNDPROC *pProc)
{
    ATOM atom;

    FIXME("%p %p %p semi-stub\n", pm, wci, pProc);

    atom = wci->m_atom;
    if (!atom)
    {
        WNDCLASSEXA wc;

        TRACE("wci->m_wc.lpszClassName = %s\n", wci->m_wc.lpszClassName);

        if (wci->m_lpszOrigName)
            FIXME( "subclassing %s not implemented\n", debugstr_a(wci->m_lpszOrigName));

        if (!wci->m_wc.lpszClassName)
        {
            snprintf(wci->m_szAutoName, sizeof(wci->m_szAutoName), "ATL%08lx", (UINT_PTR)wci);
            TRACE("auto-generated class name %s\n", wci->m_szAutoName);
            wci->m_wc.lpszClassName = wci->m_szAutoName;
        }

        atom = GetClassInfoExA(pm->m_hInst, wci->m_wc.lpszClassName, &wc);
        if (!atom)
        {
            wci->m_wc.hInstance = pm->m_hInst;
            wci->m_wc.hCursor   = LoadCursorA( wci->m_bSystemCursor ? NULL : pm->m_hInst,
                                               wci->m_lpszCursorID );
            atom = RegisterClassExA(&wci->m_wc);
        }
        wci->pWndProc = wci->m_wc.lpfnWndProc;
        wci->m_atom = atom;
    }

    if (wci->m_lpszOrigName) *pProc = wci->pWndProc;

    TRACE("returning 0x%04x\n", atom);
    return atom;
}
Example #17
0
File: main.cpp Project: 3A9C/ITstep
BOOL InitInstance(HANDLE hInstance) {

    WNDCLASSEX wcex;
    RECT rect;
    int height, width;

    memset(&wcex, 0x00, sizeof(wcex));

    wcex.cbSize = sizeof(WNDCLASSEX);
    wcex.style = CS_HREDRAW | CS_VREDRAW;
    wcex.lpfnWndProc = WndProc;
    wcex.hInstance = hInstance;
    wcex.lpszClassName = ClassName;

    RegisterClassExA(&wcex);


    //calculate required window width and height, taking in account the required client area and borders
    height = BoardHeight*BlockSize;
    width = BoardWidth*BlockSize;

    rect.left = 0;
    rect.top = 0;
    rect.bottom = height;
    rect.right = width;
    AdjustWindowRectEx(&rect, WS_OVERLAPPEDWINDOW, FALSE, WS_EX_TOPMOST);

    height += ((rect.bottom - rect.top) - height);
    width += ((rect.right - rect.left) - width);
    /////////////////////////////////////////////////

    if ((hWndMain = CreateWindowExA(WS_EX_TOPMOST, ClassName, MainTitle, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, width, height, NULL, NULL, hInstance, NULL)) == NULL) {
        return FALSE;
    }

    ShowWindow(hWndMain, SW_SHOW);
    UpdateWindow(hWndMain);

    return TRUE;
}
Example #18
0
//--------------------------------------------------------------------------
void VeWindows::_CreateWindow(Window* pkWindow)
{
	WNDCLASSEXA kClass;
	kClass.cbSize = sizeof(WNDCLASSEXA);
	kClass.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
	kClass.lpfnWndProc = WndProc;
	kClass.cbClsExtra = 0;
	kClass.cbWndExtra = 0;
	kClass.hInstance = m_kParams.m_hInstance;
	kClass.hIcon = 0;
	kClass.hCursor = LoadCursor(NULL, IDC_ARROW);
	kClass.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
	kClass.lpszMenuName = NULL;
	kClass.lpszClassName = m_kParams.m_pcAppName;
	kClass.hIconSm = 0;
	VE_ASSERT_NOT_EQ(RegisterClassExA(&kClass), VE_FALSE);
	HWND hWnd;
	RECT kRect;
	DWORD dwStyle = STYLE_BASIC;
	VeInt32 x, y;
	VeInt32 w, h;
	dwStyle |= GetWindowStyle(pkWindow);
	kRect.left = pkWindow->x;
	kRect.top = pkWindow->y;
	kRect.right = pkWindow->x + pkWindow->w;
	kRect.bottom = pkWindow->y + pkWindow->h;
	AdjustWindowRectEx(&kRect, dwStyle, FALSE, 0);
	x = kRect.left;
	y = kRect.top;
	w = (kRect.right - kRect.left);
	h = (kRect.bottom - kRect.top);
	hWnd = CreateWindowA(m_kParams.m_pcAppName, "", dwStyle, x, y, w, h, NULL, NULL,
		m_kParams.m_hInstance, NULL);
	VE_ASSERT(hWnd);
	_PumpEvents();
	SetupWindowData(pkWindow, hWnd, VE_TRUE);
	_DisableIME(pkWindow);
}
Example #19
0
bool pinDialogPriv::doNonmodalNotifyDlg(bool messageLoop) {
	MSG  msg ;    
	HWND hwnd = GetForegroundWindow();

	WNDCLASSEXA wc = {0};
	wc.cbSize           = sizeof(WNDCLASSEX);
	wc.lpfnWndProc      = (WNDPROC) nonmodalDialogProc;
	wc.hInstance        = params.m_hInst;
	wc.hbrBackground    = GetSysColorBrush(COLOR_3DFACE);
	wc.lpszClassName    = "DialogClass";
	RegisterClassExA(&wc);

	m_hwnd = CreateWindowExA(WS_EX_DLGMODALFRAME | WS_EX_TOPMOST,  "DialogClass", "PIN message", 
		WS_VISIBLE | WS_SYSMENU | WS_CAPTION , 100, 100, 380, 80, 
		NULL, NULL, params.m_hInst,  this);
	int counter = 20; //always pump some messages, like dialog init
	while( GetMessage(&msg, NULL, 0, 0) && counter--) {
		DispatchMessage(&msg);
		if (messageLoop) counter = 20; 
		}

	return true;
	}
Example #20
0
	void createWindow()
	{
		HINSTANCE hInst = GetModuleHandle(NULL);
		WNDCLASSEX wnd;
		wnd = {};
		wnd.cbSize = sizeof(wnd);
		wnd.style = CS_HREDRAW | CS_VREDRAW;
		wnd.lpfnWndProc = msgProc;
		wnd.hInstance = hInst;
		wnd.hIcon = LoadIcon(NULL, IDI_APPLICATION);
		wnd.hCursor = LoadCursor(NULL, IDC_ARROW);
		wnd.lpszClassName = "App";
		wnd.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
		RegisterClassExA(&wnd);
		m_hwnd = CreateWindowA("App", "App", WS_OVERLAPPEDWINDOW | WS_VISIBLE, 0, 0, 800, 600, NULL, NULL, hInst, 0);

		RAWINPUTDEVICE Rid;
		Rid.usUsagePage = 0x01;
		Rid.usUsage = 0x02;
		Rid.dwFlags = 0;
		Rid.hwndTarget = 0;
		RegisterRawInputDevices(&Rid, 1, sizeof(Rid));
	}
Example #21
0
static int
Win32_RegisterClass(Jim_Interp *interp, int objc, Jim_Obj *const objv[])
{
    WNDCLASSEXA wc;

    if (objc < 2 || objc > 3) {
        Jim_WrongNumArgs(interp, 1, objv, "classname ?windowproc?");
        return JIM_ERR;
    }

    // FIX ME: deal with the windowproc

    wc.cbSize        = sizeof(WNDCLASSEX);
    wc.style         = CS_HREDRAW | CS_VREDRAW;
    wc.lpfnWndProc   = DefWindowProc;
    wc.cbClsExtra    = 16;
    wc.cbWndExtra    = 0;
    wc.hInstance     = g_hInstance;
    wc.hIcon         = LoadIcon(NULL, IDI_APPLICATION);
    wc.hIconSm       = LoadIcon(NULL, IDI_APPLICATION);
    wc.hCursor       = LoadCursor(NULL, IDC_ARROW);
    wc.hbrBackground = (HBRUSH)(COLOR_BTNFACE+1);
    wc.lpszMenuName  =  wc.lpszClassName = Jim_GetString(objv[1], NULL);

    if (objc == 3) {
        wc.lpfnWndProc = JimWin32WindowProc;
    }
    
    if (!RegisterClassExA(&wc)) {
        Jim_SetResult(interp,
            Win32ErrorObj(interp, "RegisterClassEx", GetLastError()));
        return JIM_ERR;
    }

    return JIM_OK;
}
Example #22
0
int DigitalWatchWindow::Create(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
	char szWindowClass[100];
	char szTitle[100];

	sprintf((char *)&szWindowClass, "DIGITALWATCH_BDA");
	sprintf((char *)&szTitle, "DigitalWatch");

	g_pData->hWnd = FindWindowW(CA2W(szWindowClass), NULL);

	//LATER: Option for multiple instances
	if (g_pData->hWnd != NULL && !g_pData->settings.application.multiple)
	{
		(log << "An instance of Digital Watch is already running.\n  Bringing the existing instance to the foreground.\n").Write();
		SetForegroundWindow(g_pData->hWnd);
		return FALSE;
	}

//	if (g_pData->hWnd != NULL && g_pData->settings.application.multiple)
//		g_pData->values.application.multiple = g_pData->settings.application.multiple;

	HBRUSH br = CreateSolidBrush(0x00000000);

	WNDCLASSEXA wcex;
	wcex.cbSize = sizeof(WNDCLASSEXA);

	wcex.style			= CS_DBLCLKS;// | CS_HREDRAW | CS_VREDRAW;// | CS_NOCLOSE | CS_DBLCLKS;
	wcex.lpfnWndProc	= (WNDPROC)MainWndProc;
	wcex.cbClsExtra		= 0;
	wcex.cbWndExtra		= 0;
	wcex.hInstance		= 0;
	wcex.hIcon			= LoadIcon(hInstance, (LPCTSTR)IDI_DIGITALWATCH);
	wcex.hCursor		= LoadCursor(NULL, IDC_ARROW);
	wcex.hbrBackground	= br;
	wcex.lpszMenuName	= 0;
	wcex.lpszClassName	= szWindowClass;
	wcex.hIconSm		= LoadIcon(wcex.hInstance, (LPCTSTR)IDI_SMALL);

	ATOM ar = RegisterClassExA(&wcex);

	USES_CONVERSION;
	g_pData->hWnd = CreateWindowA(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW/*WS_THICKFRAME*/, CW_USEDEFAULT, 0, 726, 435, NULL, NULL, NULL, NULL);
	if (!g_pData->hWnd)
	{
		__int64 err = GetLastError();
		//return_FALSE_SHOWMSG("Error creating window: " << err)
		return (log << "Error creating window: " << err << "\n").Show();
	}

	SetWindowLong(g_pData->hWnd, GWL_STYLE, GetWindowLong(g_pData->hWnd, GWL_STYLE) & (~(WS_CAPTION/* | WS_BORDER*/))); 

	if (g_pData->settings.window.startAtLastWindowPosition && g_pData->settings.loadedFromFile)
	{
		(log << "Restoring last window position. x=" << g_pData->values.window.position.x << " y=" << g_pData->values.window.position.y << " width=" <<g_pData->values.window.size.width << " height=" << g_pData->values.window.size.height << "\n").Write();
	}
	
	BOOL bFullscreen = g_pData->values.window.bFullScreen;
	g_pData->values.window.bFullScreen = FALSE;
	g_pTv->SetWindowPos(g_pData->values.window.position.x, g_pData->values.window.position.y, g_pData->values.window.size.width, g_pData->values.window.size.height, g_pData->settings.window.startAtLastWindowPosition && g_pData->settings.loadedFromFile, TRUE);
	g_pData->values.window.bFullScreen = bFullscreen;

	ShowWindow(g_pData->hWnd, nCmdShow);
	UpdateWindow(g_pData->hWnd);

	if (g_pData->settings.window.startFullscreen != 0)
	{
		(log << "Restoring fullscreen state\n").Write();
		g_pTv->Fullscreen();
	}
	if (g_pData->settings.window.startAlwaysOnTop != 0)
	{
		(log << "Restoring always on top\n").Write();
		g_pTv->AlwaysOnTop();
	}

	return TRUE;
}
Example #23
0
	int RetRotMainLoop()
	{
		isStarted = true;

		HWND hWnd;
		WNDCLASSEXA winc;
		MSG msg;
		HINSTANCE hInstance = GetModuleHandle(NULL);

		g_pixSz = Settings.initialPixelSize;
		g_fullScr = Settings.initialFullScrMode;

		ImmDisableIME((DWORD)-1);

		winc.cbSize = sizeof(WNDCLASSEX);
		winc.style = CS_HREDRAW | CS_VREDRAW;
		winc.lpfnWndProc = WndProc;
		winc.cbClsExtra = 0;
		winc.cbWndExtra = 0;
		winc.hInstance = hInstance;
		winc.hIcon = (HICON)LoadImage(hInstance, MAKEINTRESOURCE(Settings.icon), IMAGE_ICON, 0, 0, LR_DEFAULTSIZE | LR_SHARED);
		winc.hIconSm = NULL;
		winc.hCursor = (HCURSOR)LoadImage(NULL, IDC_ARROW, IMAGE_CURSOR, 0, 0, LR_DEFAULTSIZE | LR_SHARED);
		winc.hbrBackground = CreateSolidBrush(GetSysColor(COLOR_MENU));
		winc.lpszMenuName = NULL;
		winc.lpszClassName = "MAIN";

		if (!RegisterClassExA(&winc)) {
			return 0;
		}

		SIZE sz = GetWindowSize();

		if (Settings.WndMenu != NULL)
		{
			hWndMenu = Settings.WndMenu;
		}
		else
		{
			hWndMenu = LoadMenu(GetModuleHandle(NULL), MAKEINTRESOURCE(Settings.WndMenuID));
		}

		hWnd = CreateWindowA(
			"MAIN",
			Settings.title,
			g_fullScr ? WS_FULLSCRMODE : (Settings.ScreenOnly ? WS_WINDOWMODE_NOFRAME : WS_WINDOWMODE),
			g_fullScr ? 0 : CW_USEDEFAULT,
			g_fullScr ? 0 : CW_USEDEFAULT,
			sz.cx,
			sz.cy,
			NULL,
			hWndMenu != NULL ? hWndMenu : NULL,
			hInstance,
			NULL
			);

		if (hWnd == NULL) {
			return 0;
		}

		FpsControl fc;

		do {
			if (PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE)) {
				BOOL ret = GetMessage(&msg, NULL, 0, 0);
				if (ret == 0 || ret == -1) {
					break;
				}
				DispatchMessage(&msg);
			}
			else
			{
				Sleep(1);
			}
		} while (msg.message != WM_QUIT);

		isStarted = false;

		return (int)msg.wParam;
	}
Example #24
0
INT WINAPI WinMain(HINSTANCE hInst, HINSTANCE ignoreMe0, LPSTR ignoreMe1, INT ignoreMe2)
{
    LPCSTR szName = "Pez App";
    WNDCLASSEXA wc = { sizeof(WNDCLASSEX), CS_CLASSDC | CS_DBLCLKS, MsgProc, 0L, 0L, GetModuleHandle(0), 0, 0, 0, 0, szName, 0 };
    DWORD dwStyle = WS_SYSMENU | WS_VISIBLE | WS_POPUP;
    DWORD dwExStyle = WS_EX_APPWINDOW | WS_EX_WINDOWEDGE;
    RECT rect;
    int windowWidth, windowHeight, windowLeft, windowTop;
    HWND hWnd;
    PIXELFORMATDESCRIPTOR pfd;
    HDC hDC;
    HGLRC hRC;
    int pixelFormat;
    GLenum err;
    MSG msg = {0};
    LARGE_INTEGER previousTime;
    LARGE_INTEGER freqTime;

    wc.hCursor = LoadCursor(0, IDC_ARROW);
    RegisterClassExA(&wc);

    SetRect(&rect, 0, 0, PEZ_VIEWPORT_WIDTH, PEZ_VIEWPORT_HEIGHT);
    AdjustWindowRectEx(&rect, dwStyle, FALSE, dwExStyle);
    windowWidth = rect.right - rect.left;
    windowHeight = rect.bottom - rect.top;
    windowLeft = GetSystemMetrics(SM_XVIRTUALSCREEN) + GetSystemMetrics(SM_CXSCREEN) / 2 - windowWidth / 2;
    windowTop = GetSystemMetrics(SM_CYSCREEN) / 2 - windowHeight / 2;
    hWnd = CreateWindowExA(0, szName, szName, dwStyle, windowLeft, windowTop, windowWidth, windowHeight, 0, 0, 0, 0);

    // Create the GL context.
    ZeroMemory(&pfd, sizeof(pfd));
    pfd.nSize = sizeof(pfd);
    pfd.nVersion = 1;
    pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
    pfd.iPixelType = PFD_TYPE_RGBA;
    pfd.cColorBits = 24;
    pfd.cDepthBits = 0;
    pfd.cStencilBits = 0;
    pfd.iLayerType = PFD_MAIN_PLANE;

    hDC = GetDC(hWnd);
    pixelFormat = ChoosePixelFormat(hDC, &pfd);

    SetPixelFormat(hDC, pixelFormat, &pfd);
    hRC = wglCreateContext(hDC);
    wglMakeCurrent(hDC, hRC);

    if (PEZ_ENABLE_MULTISAMPLING)
    {
        int pixelAttribs[] =
        {
            WGL_SAMPLES_ARB, 16,
            WGL_SAMPLE_BUFFERS_ARB, GL_TRUE,
            WGL_DRAW_TO_WINDOW_ARB, GL_TRUE,
            WGL_SUPPORT_OPENGL_ARB, GL_TRUE,
            WGL_ACCELERATION_ARB, WGL_FULL_ACCELERATION_ARB,
            WGL_PIXEL_TYPE_ARB, WGL_TYPE_RGBA_ARB,
            WGL_RED_BITS_ARB, 8,
            WGL_GREEN_BITS_ARB, 8,
            WGL_BLUE_BITS_ARB, 8,
            WGL_ALPHA_BITS_ARB, 8,
            WGL_DEPTH_BITS_ARB, 24,
            WGL_STENCIL_BITS_ARB, 8,
            WGL_DOUBLE_BUFFER_ARB, GL_TRUE,
            0
        };
        int* sampleCount = pixelAttribs + 1;
        int* useSampleBuffer = pixelAttribs + 3;
        int pixelFormat = -1;
        PROC proc = wglGetProcAddress("wglChoosePixelFormatARB");
        unsigned int numFormats;
        PFNWGLCHOOSEPIXELFORMATARBPROC wglChoosePixelFormatARB = (PFNWGLCHOOSEPIXELFORMATARBPROC) proc;

        if (!wglChoosePixelFormatARB)
        {
            PezFatalError("Could not load function pointer for 'wglChoosePixelFormatARB'.  Is your driver properly installed?");
        }

        // Try fewer and fewer samples per pixel till we find one that is supported:
        while (pixelFormat <= 0 && *sampleCount >= 0)
        {
            wglChoosePixelFormatARB(hDC, pixelAttribs, 0, 1, &pixelFormat, &numFormats);
            (*sampleCount)--;
            if (*sampleCount <= 1)
            {
                *useSampleBuffer = GL_FALSE;
            }
        }

        // Win32 allows the pixel format to be set only once per app, so destroy and re-create the app:
        DestroyWindow(hWnd);
        hWnd = CreateWindowExA(0, szName, szName, dwStyle, windowLeft, windowTop, windowWidth, windowHeight, 0, 0, 0, 0);
        SetWindowPos(hWnd, HWND_TOP, windowLeft, windowTop, windowWidth, windowHeight, 0);
        hDC = GetDC(hWnd);
        SetPixelFormat(hDC, pixelFormat, &pfd);
        hRC = wglCreateContext(hDC);
        wglMakeCurrent(hDC, hRC);
    }

#define PEZ_TRANSPARENT_WINDOW 0

    // For transparency, this doesn't seem to work.  I think I'd need to read back from an OpenGL FBO and blit it with GDI.
    if (PEZ_TRANSPARENT_WINDOW)
    {
        long flag = GetWindowLong(hWnd, GWL_EXSTYLE);
        int opacity = 128;
        flag |= WS_EX_LAYERED;
        SetWindowLong(hWnd, GWL_EXSTYLE, flag);
        SetLayeredWindowAttributes(hWnd, 0, opacity, LWA_ALPHA);		
    }

    err = glewInit();
    if (GLEW_OK != err)
    {
        PezFatalError("GLEW Error: %s\n", glewGetErrorString(err));
    }
    PezDebugString("OpenGL Version: %s\n", glGetString(GL_VERSION));

    if (!PEZ_VERTICAL_SYNC)
    {
        wglSwapIntervalEXT(0);
    }

    if (PEZ_FORWARD_COMPATIBLE_GL)
    {
        const int contextAttribs[] =
        {
            WGL_CONTEXT_MAJOR_VERSION_ARB, 3,
            WGL_CONTEXT_MINOR_VERSION_ARB, 2,
            WGL_CONTEXT_FLAGS_ARB, WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB,
            0
        };

        HGLRC newRC = wglCreateContextAttribsARB(hDC, 0, contextAttribs);
        wglMakeCurrent(0, 0);
        wglDeleteContext(hRC);
        hRC = newRC;
        wglMakeCurrent(hDC, hRC);
    }

    {
        const char* szWindowTitle = PezInitialize(PEZ_VIEWPORT_WIDTH, PEZ_VIEWPORT_HEIGHT);
        SetWindowTextA(hWnd, szWindowTitle);
    }

    QueryPerformanceFrequency(&freqTime);
    QueryPerformanceCounter(&previousTime);

    // -------------------
    // Start the Game Loop
    // -------------------
    while (msg.message != WM_QUIT)
    {
        if (PeekMessage(&msg, 0, 0, 0, PM_REMOVE))
        {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
        else
        {
            LARGE_INTEGER currentTime;
            __int64 elapsed;
            double deltaTime;

            QueryPerformanceCounter(&currentTime);
            elapsed = currentTime.QuadPart - previousTime.QuadPart;
            deltaTime = elapsed * 1000000.0 / freqTime.QuadPart;
            previousTime = currentTime;

            PezUpdate((unsigned int) deltaTime);
            PezRender(0);
            SwapBuffers(hDC);
            PezCheckCondition(glGetError() == GL_NO_ERROR, "OpenGL error.\n");
        }
    }

    UnregisterClassA(szName, wc.hInstance);

    return 0;
}
Example #25
0
  bool Win32Window::Initialize(const char* name, size_t width, size_t height)
  {
	Destroy();
	IsMouseInWindow(false);

	parentClassName = name;
	childClassName = parentClassName + "_Child";

	// Work around compile error from not defining "UNICODE" while Chromium does
	const LPSTR idcArrow = MAKEINTRESOURCEA(32512);

	WNDCLASSEXA parentWindowClass = { 0 };
	parentWindowClass.cbSize = sizeof(WNDCLASSEXA);
	parentWindowClass.style = 0;
	parentWindowClass.lpfnWndProc = WndProc;
	parentWindowClass.cbClsExtra = 0;
	parentWindowClass.cbWndExtra = 0;
	parentWindowClass.hInstance = GetModuleHandle(NULL);
	parentWindowClass.hIcon = NULL;
	parentWindowClass.hCursor = LoadCursorA(NULL, idcArrow);
	parentWindowClass.hbrBackground = 0;
	parentWindowClass.lpszMenuName = NULL;
	parentWindowClass.lpszClassName = parentClassName.c_str();
	if (!RegisterClassExA(&parentWindowClass)) {
	  return false;
	}

	WNDCLASSEXA childWindowClass = { 0 };
	childWindowClass.cbSize = sizeof(WNDCLASSEXA);
	childWindowClass.style = CS_OWNDC;
	childWindowClass.lpfnWndProc = WndProc;
	childWindowClass.cbClsExtra = 0;
	childWindowClass.cbWndExtra = 0;
	childWindowClass.hInstance = GetModuleHandle(NULL);
	childWindowClass.hIcon = NULL;
	childWindowClass.hCursor = LoadCursorA(NULL, idcArrow);
	childWindowClass.hbrBackground = 0;
	childWindowClass.lpszMenuName = NULL;
	childWindowClass.lpszClassName = childClassName.c_str();
	if (!RegisterClassExA(&childWindowClass)) {
	  return false;
	}

	DWORD parentStyle = WS_CAPTION | WS_THICKFRAME | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_SYSMENU;
	DWORD parentExtendedStyle = WS_EX_APPWINDOW;

	RECT sizeRect = { 0, 0, static_cast<LONG>(width), static_cast<LONG>(height) };
	AdjustWindowRectEx(&sizeRect, parentStyle, FALSE, parentExtendedStyle);

	parentWindow = CreateWindowExA(
	  parentExtendedStyle,
	  parentClassName.c_str(),
	  name,
	  parentStyle,
	  CW_USEDEFAULT,
	  CW_USEDEFAULT,
	  sizeRect.right - sizeRect.left,
	  sizeRect.bottom - sizeRect.top,
	  NULL,
	  NULL,
	  GetModuleHandle(NULL),
	  this
	);

	nativeWindow = CreateWindowExA(
	  0,
	  childClassName.c_str(),
	  name,
	  WS_CHILD,
	  0,
	  0,
	  static_cast<int>(width),
	  static_cast<int>(height),
	  parentWindow,
	  NULL,
	  GetModuleHandle(NULL),
	  this
	);

	nativeDisplay = GetDC(nativeWindow);
	if (!nativeDisplay) {
	  Destroy();
	  return false;
	}

	{
	  Event event;
	  event.Type = Event::EVENT_INIT_WINDOW;
	  event.Time = GetTickCount64();
	  PushEvent(event);
	}

	return true;
  }
Example #26
0
static DWORD WINAPI detectCDThread(LPVOID lpParameter)
{
    const char *classname = "PhysicsFSDetectCDCatcher";
    const char *winname = "PhysicsFSDetectCDMsgWindow";
    HINSTANCE hInstance = GetModuleHandleW(NULL);
    ATOM class_atom = 0;
    WNDCLASSEXA wce;
    MSG msg;

    memset(&wce, '\0', sizeof (wce));
    wce.cbSize = sizeof (wce);
    wce.lpfnWndProc = detectCDWndProc;
    wce.lpszClassName = classname;
    wce.hInstance = hInstance;
    class_atom = RegisterClassExA(&wce);
    if (class_atom == 0)
    {
        initialDiscDetectionComplete = 1;  /* let main thread go on. */
        return 0;
    } /* if */

    detectCDHwnd = CreateWindowExA(0, classname, winname, WS_OVERLAPPEDWINDOW,
                        CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
                        CW_USEDEFAULT, HWND_DESKTOP, NULL, hInstance, NULL);

    if (detectCDHwnd == NULL)
    {
        initialDiscDetectionComplete = 1;  /* let main thread go on. */
        UnregisterClassA(classname, hInstance);
        return 0;
    } /* if */

    /* We'll get events when discs come and go from now on. */

    /* Do initial detection, possibly blocking awhile... */
    drivesWithMediaBitmap = pollDiscDrives();
    initialDiscDetectionComplete = 1;  /* let main thread go on. */

    do
    {
        const BOOL rc = GetMessageW(&msg, detectCDHwnd, 0, 0);
        if ((rc == 0) || (rc == -1))
            break;  /* don't care if WM_QUIT or error break this loop. */
        TranslateMessage(&msg);
        DispatchMessageW(&msg);
    } while (1);

    /* we've been asked to quit. */
    DestroyWindow(detectCDHwnd);

    do
    {
        const BOOL rc = GetMessage(&msg, detectCDHwnd, 0, 0);
        if ((rc == 0) || (rc == -1))
            break;
        TranslateMessage(&msg);
        DispatchMessageW(&msg);
    } while (1);

    UnregisterClassA(classname, hInstance);

    return 0;
} /* detectCDThread */
Example #27
0
/*
 * ::createGlInitContext
 */
BOOL createGlInitContext(GlInitContext *outCtx) {
    HINSTANCE hInst = GetModuleHandle(NULL);
    GLuint pixelFormat = 0;
    PIXELFORMATDESCRIPTOR pfd = { sizeof(PIXELFORMATDESCRIPTOR), 1,
        PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER, 
        PFD_TYPE_RGBA, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0,
        PFD_MAIN_PLANE, 0, 0, 0, 0 };
    WNDCLASSEXA wndClass;
    
    if (outCtx == NULL) {
        return FALSE;
    }

    outCtx->hWnd = NULL;
    outCtx->hDC = NULL;
    outCtx->hRC = NULL;

    /* Register window class, if not yet available. */
    if (!GetClassInfoExA(hInst, INITCTX_WNDCLASS_NAME, &wndClass)) {
        ZeroMemory(&wndClass, sizeof(WNDCLASSEX));
        wndClass.cbSize = sizeof(WNDCLASSEX);
        wndClass.style = CS_CLASSDC;
        wndClass.lpfnWndProc = DefWindowProc;
        wndClass.hInstance = hInst;
        wndClass.lpszClassName = INITCTX_WNDCLASS_NAME;

        if (!RegisterClassExA(&wndClass)) {
            dbgPrint(DBGLVL_ERROR, "Registering window class for GL detours initialisation "
                "failed: %u\n", GetLastError());
            return FALSE;
        }
    }

    /* Create window. */
    if ((outCtx->hWnd = CreateWindowExA(WS_EX_APPWINDOW, 
            INITCTX_WNDCLASS_NAME, "", WS_POPUP, 0, 0, 1, 1, NULL, NULL, hInst,
            NULL)) == NULL) {
        dbgPrint(DBGLVL_ERROR, "Creating window for GL detours initialisation failed:\n",
            GetLastError());
        releaseGlInitContext(outCtx);
        return FALSE;
    }

    /* Create OpenGL context. */
    outCtx->hDC = GetDC(outCtx->hWnd);

    if ((pixelFormat = ChoosePixelFormat(outCtx->hDC, &pfd)) == 0) {
        dbgPrint(DBGLVL_ERROR, "ChoosePixelFormat failed: %u\n", GetLastError());
        releaseGlInitContext(outCtx);
        return FALSE;
    }
    if (!SetPixelFormat(outCtx->hDC, pixelFormat, &pfd)) {
        dbgPrint(DBGLVL_ERROR, "SetPixelFormat failed: %u\n", GetLastError());
        releaseGlInitContext(outCtx);
        return FALSE;
    }

    if ((outCtx->hRC = wglCreateContext(outCtx->hDC)) == NULL) {
        dbgPrint(DBGLVL_ERROR, "wglCreateContext failed: %u\n", GetLastError());
        releaseGlInitContext(outCtx);
        return FALSE;
    }
    if (!wglMakeCurrent(outCtx->hDC, outCtx->hRC)) {
        dbgPrint(DBGLVL_ERROR, "wglMakeCurrent failed: %u\n", GetLastError());
        releaseGlInitContext(outCtx);
        return FALSE;
    }

    return TRUE;
}
Example #28
0
/******************************************************************
 *		WDML_CreateServerConv
 *
 *
 */
static WDML_CONV* WDML_CreateServerConv(WDML_INSTANCE* pInstance, HWND hwndClient,
					HWND hwndServerName, HSZ hszApp, HSZ hszTopic)
{
    HWND	hwndServerConv;
    WDML_CONV*	pConv;

    if (pInstance->unicode)
    {
	WNDCLASSEXW	wndclass;

	wndclass.cbSize        = sizeof(wndclass);
	wndclass.style         = 0;
	wndclass.lpfnWndProc   = WDML_ServerConvProc;
	wndclass.cbClsExtra    = 0;
	wndclass.cbWndExtra    = 2 * sizeof(DWORD);
	wndclass.hInstance     = 0;
	wndclass.hIcon         = 0;
	wndclass.hCursor       = 0;
	wndclass.hbrBackground = 0;
	wndclass.lpszMenuName  = NULL;
	wndclass.lpszClassName = WDML_szServerConvClassW;
	wndclass.hIconSm       = 0;

	RegisterClassExW(&wndclass);

	hwndServerConv = CreateWindowW(WDML_szServerConvClassW, 0,
				       WS_CHILD, 0, 0, 0, 0,
				       hwndServerName, 0, 0, 0);
    }
    else
    {
	WNDCLASSEXA	wndclass;

	wndclass.cbSize        = sizeof(wndclass);
	wndclass.style         = 0;
	wndclass.lpfnWndProc   = WDML_ServerConvProc;
	wndclass.cbClsExtra    = 0;
	wndclass.cbWndExtra    = 2 * sizeof(DWORD);
	wndclass.hInstance     = 0;
	wndclass.hIcon         = 0;
	wndclass.hCursor       = 0;
	wndclass.hbrBackground = 0;
	wndclass.lpszMenuName  = NULL;
	wndclass.lpszClassName = WDML_szServerConvClassA;
	wndclass.hIconSm       = 0;

	RegisterClassExA(&wndclass);

	hwndServerConv = CreateWindowA(WDML_szServerConvClassA, 0,
				       WS_CHILD, 0, 0, 0, 0,
				       hwndServerName, 0, 0, 0);
    }

    TRACE("Created convServer=%04x (nameServer=%04x) for instance=%08lx\n",
	  hwndServerConv, hwndServerName, pInstance->instanceID);

    pConv = WDML_AddConv(pInstance, WDML_SERVER_SIDE, hszApp, hszTopic,
			 hwndClient, hwndServerConv);
    if (pConv)
    {
	SetWindowLongA(hwndServerConv, GWL_WDML_INSTANCE, (DWORD)pInstance);
	SetWindowLongA(hwndServerConv, GWL_WDML_CONVERSATION, (DWORD)pConv);

	/* this should be the only place using SendMessage for WM_DDE_ACK */
        /* note: sent messages shall not use packing */
	SendMessageA(hwndClient, WM_DDE_ACK, (WPARAM)hwndServerConv,
		     MAKELPARAM(WDML_MakeAtomFromHsz(hszApp), WDML_MakeAtomFromHsz(hszTopic)));
	/* we assume we're connected since we've sent an answer...
	 * I'm not sure what we can do... it doesn't look like the return value
	 * of SendMessage is used... sigh...
	 */
	pConv->wStatus |= ST_CONNECTED;
    }
    else
    {
	DestroyWindow(hwndServerConv);
    }
    return pConv;
}
Example #29
0
bool NativeApp::PreInit() {
	
	COut(C_Info) << "Detecting video system..." << std::endl;

//#define HACK_DISABLE_GL
#if defined(RAD_OPT_GL) && !defined(HACK_DISABLE_GL)

	{
		WNDCLASSEXA clex;
		memset(&clex, 0, sizeof(WNDCLASSEXA));

		clex.cbSize = sizeof(WNDCLASSEXA);
		clex.style = CS_OWNDC;
		clex.lpfnWndProc = DefWindowProc;
		clex.hInstance = s_hInstance;
		clex.lpszClassName = "rad_openGL_ini";

		RegisterClassExA(&clex);
	}

	HWND wglWnd = CreateWindowA(
		"rad_openGL_ini", 
		"", 
		WS_CLIPCHILDREN|WS_CLIPSIBLINGS,
		0,
		0,
		100,
		100,
		0,
		0,
		s_hInstance,
		0
	);

	if (!wglWnd) {
		COut(C_Error) << "ERROR: Unable to create device window!" << std::endl;
		return false;
	}

	HDC wglDC = GetDC(wglWnd);

	{
		PIXELFORMATDESCRIPTOR pfd;
		memset(&pfd, 0, sizeof(PIXELFORMATDESCRIPTOR));
		pfd.nSize = sizeof(PIXELFORMATDESCRIPTOR);
		pfd.nVersion = 1;
		pfd.dwFlags = PFD_DRAW_TO_WINDOW|PFD_SUPPORT_OPENGL|PFD_DOUBLEBUFFER;
		pfd.iPixelType = PFD_TYPE_RGBA;
		pfd.cColorBits = 24;
		pfd.cAlphaBits = 8;
		pfd.cDepthBits = 24;
		pfd.cStencilBits = 8;
		pfd.iLayerType = PFD_MAIN_PLANE;

		int pf = ChoosePixelFormat(wglDC, &pfd);
		if (pf < 1) {
			ReleaseDC(wglWnd, wglDC);
			DestroyWindow(wglWnd);
			COut(C_Error) << "ERROR: Unable to bind device window pixel format!" << std::endl;
			return false;
		}

		DescribePixelFormat(wglDC, pf, sizeof(PIXELFORMATDESCRIPTOR), &pfd);

		if (!SetPixelFormat(wglDC, pf, &pfd)) {
			COut(C_Error) << "ERROR: Unable to bind device window pixel format!" << std::endl;
			return false;
		}
	}

	HGLRC wglRC = myWglCreateContex(wglDC);
	
	if (!wglRC) {
		COut(C_Error) << "ERROR: Unable to create device window context!" << std::endl;
		return false;
	}

	wglMakeCurrent(wglDC, wglRC);
	
	PFNWGLGETEXTENSIONSSTRINGARBPROC wglGetExtensionsStringARB = (PFNWGLGETEXTENSIONSSTRINGARBPROC)wglGetProcAddress("wglGetExtensionsStringARB");
	if (!wglGetExtensionsStringARB) {
		wglGetExtensionsStringARB = (PFNWGLGETEXTENSIONSSTRINGARBPROC)wglGetProcAddress("wglGetExtensionsStringEXT");
		if (!wglGetExtensionsStringARB) {
			wglMakeCurrent(0, 0);
			wglDeleteContext(wglRC);
			ReleaseDC(wglWnd, wglDC);
			DestroyWindow(wglWnd);
			COut(C_Error) << "Unable to find wglGetExtensionsStringARB" << std::endl;
			return false;
		}
	}

	const char *wglStrings = wglGetExtensionsStringARB(wglDC);

	if (wglStrings)
		COut(C_Info) << "wglGetExtensionsStringARB: " << wglStrings << std::endl;

	if (!wglStrings || !string::strstr(wglStrings, "WGL_ARB_pixel_format")) {
		wglMakeCurrent(0, 0);
		wglDeleteContext(wglRC);
		ReleaseDC(wglWnd, wglDC);
		DestroyWindow(wglWnd);
		COut(C_Error) << "WGL_ARB_pixel_format is required but not found." << std::endl;
		return false;
	}

	bool multiSample = false;
	if (string::strstr(wglStrings, "WGL_ARB_multisample"))
		multiSample = true;

	PFNWGLCHOOSEPIXELFORMATARBPROC wglChoosePixelFormatARB = (PFNWGLCHOOSEPIXELFORMATARBPROC)wglGetProcAddress("wglChoosePixelFormatARB");
	PFNWGLGETPIXELFORMATATTRIBIVARBPROC wglGetPixelFormatAttribivARB = (PFNWGLGETPIXELFORMATATTRIBIVARBPROC)wglGetProcAddress("wglGetPixelFormatAttribivARB");

#endif

	DISPLAY_DEVICEA wdd;
	for (int i = 0; ; ++i) {
		wdd.cb = sizeof(DISPLAY_DEVICEA);
		if (!EnumDisplayDevicesA(0, (DWORD)i, &wdd, 0))
			break;
		if (!(wdd.StateFlags&DISPLAY_DEVICE_ACTIVE))
			continue;
		
		::DisplayDevice::Ref _dd(new (ZEngine) ::DisplayDevice());
		DisplayDevice *dd = &_dd->m_imp;

		dd->m_vars.reset(new (ZEngine) DDVars());
		DDVars *ddv = DDVars::Get(dd->m_vars);

		memcpy(&ddv->dd, &wdd, sizeof(DISPLAY_DEVICEA));

		if (wdd.StateFlags&DISPLAY_DEVICE_PRIMARY_DEVICE) {
			dd->m_primary = true;
		} else {
			dd->m_primary = false;
		}

		DEVMODEA dm;
		dm.dmSize = sizeof(DEVMODEA);

		BOOL r = EnumDisplaySettingsA(ddv->dd.DeviceName, ENUM_CURRENT_SETTINGS, &dm);

		if (!r || ((dm.dmFields&kRequiredDMFields) != kRequiredDMFields)) {
			if (dd->m_primary) {
				// this is kinda bad
				COut(C_Error) << "ERROR: failed to enumerate primary display, initialization failed." << std::endl;
				return false;
			}

			continue;
		}

		if (!(dm.dmFields & DM_POSITION)) {
			// dmPosition is not valid, meaning we cannot identify this as secondary monitor...
			if (dd->m_primary) {
				dm.dmPosition.x = 0;
				dm.dmPosition.y = 0;
				dm.dmFields |= DM_POSITION;
			} else {
				continue; // this monitor cannot be identified.
			}
		}

		string::ncpy((char*)dm.dmDeviceName, wdd.DeviceName, 32);
		memcpy(&ddv->dm, &dm, sizeof(DEVMODEA));
		dd->m_defMode = VidModeFromDevMode(dm);
		dd->m_curMode = dd->m_defMode;
		dd->m_maxMSAA = 0;
		dd->m_maxAnisotropy = 0;

		// enumerate valid display modes.
		COut(C_Info) << "Display " << i << ": '" << ddv->dd.DeviceName << " - " << ddv->dd.DeviceString << "':" << std::endl;

		for (int k = 0; ; ++k) {
			dm.dmSize = sizeof(DEVMODEA);
			if (!EnumDisplaySettingsA(ddv->dd.DeviceName, k, &dm))
				break;
			if ((dm.dmFields&kRequiredDMFields) != kRequiredDMFields)
				continue;
			if (dm.dmBitsPerPel < 32)
				continue;
			r::VidMode m = VidModeFromDevMode(dm);

			r::VidModeVec::iterator it;
			for (it = dd->m_vidModes.begin(); it != dd->m_vidModes.end(); ++it) {
				r::VidMode &x = *it;

				if (x.w == m.w &&
					x.h == m.h) {
					// matches.
					// prefer we use the same hz as our desktop...
					if (m.hz == dd->m_defMode.hz)
						x.hz = m.hz;
					break;
				}
			}

			if (it == dd->m_vidModes.end())
				dd->m_vidModes.push_back(m);
		}

		for (r::VidModeVec::const_iterator it = dd->m_vidModes.begin(); it != dd->m_vidModes.end(); ++it) {
			const r::VidMode &m = *it;
			COut(C_Info) << "\t" << (it-dd->m_vidModes.begin()) << ": " << m.w << "x" << m.h << "x" << m.bpp << " @ " << m.hz << "hz" << std::endl;
		}

		if (dd->m_vidModes.empty()) {
			if (dd->m_primary) {
				COut(C_Error) << "ERROR: primary display '" << ddv->dd.DeviceName << "' is invalid, initialization failed." << std::endl;
				return false;
			}
			continue;
		}

#if defined(RAD_OPT_GL) && !defined(HACK_DISABLE_GL)
		if (multiSample) {

			int maxSamples = 0;

			int reqAttribs[9] = {
				WGL_SUPPORT_OPENGL_ARB,
				WGL_DRAW_TO_WINDOW_ARB,
				WGL_ACCELERATION_ARB,
				WGL_PIXEL_TYPE_ARB,
				WGL_COLOR_BITS_ARB,
				WGL_ALPHA_BITS_ARB,
				WGL_DEPTH_BITS_ARB,
				WGL_STENCIL_BITS_ARB,
				WGL_SAMPLES_ARB
			};

			int attribs[9];

			// Enumerate all pixel formats, find highest multi-sample count
			for (int k = 1; ; ++k) { // PF's are 1 based
				if (!wglGetPixelFormatAttribivARB(wglDC, k, PFD_MAIN_PLANE, 9, reqAttribs, attribs))
					break;
				if (attribs[0] != TRUE)
					continue;
				if (attribs[1] != TRUE)
					continue;
				if (attribs[2] != WGL_FULL_ACCELERATION_ARB)
					continue;
				if (attribs[3] != WGL_TYPE_RGBA_ARB)
					continue;
				if (attribs[4] < 24)
					continue;
				if (attribs[5] < 8)
					continue;
				if (attribs[6] < 24)
					continue;
				if (attribs[7] < 8)
					continue;

				if (maxSamples < attribs[8])
					maxSamples = attribs[8];

				if (maxSamples >= kMaxMultiSample)
					break;
			}

			dd->m_maxMSAA = maxSamples;
		}

		const char *glExt = (const char *)glGetString(GL_EXTENSIONS);
		if (glExt && string::strstr(glExt, "GL_EXT_texture_filter_anisotropic")) {
			GLint maxAnisotropy;
			glGetIntegerv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &maxAnisotropy);
			dd->m_maxAnisotropy = maxAnisotropy;
		}
		
#endif

		m_displayDevices.push_back(_dd);

		if (dd->m_primary)
			m_primaryDisplay = _dd;
	}

	if (!m_primaryDisplay) {
		COut(C_Error) << "ERROR: no primary display detected, initialization failed!" << std::endl;
		return false;
	}

	return true;
}
int CALLBACK WinMain(HINSTANCE Instance, HINSTANCE PrevInstance, LPSTR CommandLine, int ShowCode) {
	win32_state Win32State = {};

	LARGE_INTEGER PerfCounterFrequencyResult;
	QueryPerformanceFrequency(&PerfCounterFrequencyResult);
	GlobalPerfCounterFrequency = PerfCounterFrequencyResult.QuadPart;

	Win32GetEXEFileName(&Win32State);
	char SourceGameCodeDLLFullPath[WIN32_STATE_FILE_NAME_COUNT];
	Win32BuildEXEPathFileName(&Win32State, "handmade.dll", sizeof(SourceGameCodeDLLFullPath), SourceGameCodeDLLFullPath);
	char TempGameCodeDLLFullPath[WIN32_STATE_FILE_NAME_COUNT];
	Win32BuildEXEPathFileName(&Win32State, "handmade_temp.dll", sizeof(TempGameCodeDLLFullPath), TempGameCodeDLLFullPath);
	char GameCodeLockFullPath[WIN32_STATE_FILE_NAME_COUNT];
	Win32BuildEXEPathFileName(&Win32State, "lock.tmp", sizeof(GameCodeLockFullPath), GameCodeLockFullPath);

	// NOTE: setting windows scheduler granularity for our sleep() call
	UINT DesiredSchedulerMS = 1;
	bool32 SleepIsGranular = (timeBeginPeriod(DesiredSchedulerMS) == TIMERR_NOERROR);

	Win32LoadXInput();
	Win32ResizeDIBSection(&GlobalBackbuffer, 960, 540);

#if HANDMADE_INTERNAL
	DEBUGGlobalShowCursor = true;
#endif

	WNDCLASSEXA WindowClass = {};
	WindowClass.style = CS_VREDRAW | CS_HREDRAW;
	WindowClass.cbSize = sizeof(WNDCLASSEXA);
	WindowClass.lpfnWndProc = Win32MainWindowCallback;
	WindowClass.hInstance = Instance;
	WindowClass.hCursor = LoadCursor(0, IDC_ARROW);
	// WindowClass.hIcon;
	WindowClass.lpszClassName = "HandmadeHeroWindowClass";

	if (RegisterClassExA(&WindowClass)) {
		// WS_EX_TOPMOST|WS_EX_LAYERED
		HWND Window = CreateWindowExA(0, WindowClass.lpszClassName, "Handmade Hero", WS_OVERLAPPEDWINDOW | WS_VISIBLE, CW_USEDEFAULT, CW_USEDEFAULT, 996, 600, 0, 0, Instance, 0);

		if (Window) {
			// TODO: reliably query this from windows
			int MonitorRefreshHz = 60;
			HDC RefreshDC = GetDC(Window);
			int Win32RefreshRate = GetDeviceCaps(RefreshDC, VREFRESH);
			ReleaseDC(Window, RefreshDC);
			if (Win32RefreshRate > 1) {
				MonitorRefreshHz = Win32RefreshRate;

				if (MonitorRefreshHz == 59) {
					MonitorRefreshHz = 60;
				}
			}
			real32 GameUpdateHz = MonitorRefreshHz / 2.0f;
			real32 TargetSecondsPerFrame = 1.0f / GameUpdateHz;

			// NOTE: sound test
			win32_sound_output SoundOutput = {};
			SoundOutput.SamplesPerSecond = 48000;
			SoundOutput.BytesPerSample = sizeof(int16) * 2;
			SoundOutput.SecondaryBufferSize = SoundOutput.SamplesPerSecond * SoundOutput.BytesPerSample;
			// TODO: compute this variance and see what the lowest reasonable value is
			SoundOutput.SafetyBytes = (int)((real32)SoundOutput.SamplesPerSecond * (real32)SoundOutput.BytesPerSample / GameUpdateHz / 3.0f);

			Win32InitDSound(Window, SoundOutput.SamplesPerSecond, SoundOutput.SecondaryBufferSize);
			Win32ClearSoundBuffer(&SoundOutput);
			GlobalSecondaryBuffer->Play(0, 0, DSBPLAY_LOOPING);

			GlobalRunning = true;

			// TODO: pool with bitmap virtualalloc
			int16 *Samples = (int16 *)VirtualAlloc(0, SoundOutput.SecondaryBufferSize, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);

#if HANDMADE_INTERNAL
			LPVOID BaseAddress = (LPVOID)Terabytes(2);
#else
			LPVOID BaseAddress = 0;
#endif

			game_memory GameMemory = {};
			GameMemory.PermanentStorageSize = Megabytes(64);
			GameMemory.TransientStorageSize = Gigabytes(1);
			GameMemory.DEBUGPlatformFreeFileMemory = DEBUGPlatformFreeFileMemory;
			GameMemory.DEBUGPlatformReadEntireFile = DEBUGPlatformReadEntireFile;
			GameMemory.DEBUGPlatformWriteEntireFile = DEBUGPlatformWriteEntireFile;

			// TODO: handle various memory footprints using system metrics
			// TODO: use MEM_LARGE_PAGES
			Win32State.TotalSize = GameMemory.PermanentStorageSize + GameMemory.TransientStorageSize;
			Win32State.GameMemoryBlock = VirtualAlloc(BaseAddress, (size_t)Win32State.TotalSize, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
			GameMemory.PermanentStorage = Win32State.GameMemoryBlock;
			GameMemory.TransientStorage = (uint8 *)GameMemory.PermanentStorage + GameMemory.PermanentStorageSize;

			for (int ReplayIndex = 1; ReplayIndex < ArrayCount(Win32State.ReplayBuffers); ++ReplayIndex) {
				// TODO: recording system still takes too long on record start
				win32_replay_buffer *ReplayBuffer = &Win32State.ReplayBuffers[ReplayIndex];

				Win32GetInputFileLocation(&Win32State, false, ReplayIndex, sizeof(ReplayBuffer->FileName), ReplayBuffer->FileName);
				ReplayBuffer->FileHandle = CreateFileA(ReplayBuffer->FileName, GENERIC_READ | GENERIC_WRITE, 0, 0, CREATE_ALWAYS, 0, 0);

				LARGE_INTEGER MaxSize;
				MaxSize.QuadPart = Win32State.TotalSize;
				ReplayBuffer->MemoryMap = CreateFileMapping(ReplayBuffer->FileHandle, 0, PAGE_READWRITE, MaxSize.HighPart, MaxSize.LowPart, 0);
				ReplayBuffer->MemoryBlock = MapViewOfFile(ReplayBuffer->MemoryMap, FILE_MAP_ALL_ACCESS, 0, 0, (size_t)Win32State.TotalSize);

				if (!ReplayBuffer->MemoryBlock) {
					// TODO: diagnostic
				}
			}

			if (Samples && GameMemory.PermanentStorage && GameMemory.TransientStorage) {
				game_input Input[2] = {};
				game_input *NewInput = &Input[0];
				game_input *OldInput = &Input[1];

				LARGE_INTEGER LastCounter = Win32GetWallClock();
				LARGE_INTEGER FlipWallClock = Win32GetWallClock();

				int DebugTimeMarkerIndex = 0;
				win32_debug_time_marker DebugTimeMarkers[30] = { 0 };

				// TODO: handle startup specially
				bool32 SoundIsValid = false;
				DWORD AudioLatencyBytes = 0;
				real32 AudioLatencySeconds = 0;

				win32_game_code Game = Win32LoadGameCode(SourceGameCodeDLLFullPath, TempGameCodeDLLFullPath, GameCodeLockFullPath);

				uint64 LastCycleCount = __rdtsc();

				while (GlobalRunning) {
					NewInput->FrameTimeDelta = TargetSecondsPerFrame;

					FILETIME NewDLLWriteTime = Win32GetLastWriteTime(SourceGameCodeDLLFullPath);
					if (CompareFileTime(&NewDLLWriteTime, &Game.DLLLastWriteTime) != 0) {
						Win32UnloadGameCode(&Game);
						Game = Win32LoadGameCode(SourceGameCodeDLLFullPath, TempGameCodeDLLFullPath, GameCodeLockFullPath);
					}

					// TODO: zeroing macro
					// TODO: we cant zero everything as the up/down state will be wrong
					game_controller_input *OldKeyboardController = GetController(OldInput, 0);
					game_controller_input *NewKeyboardController = GetController(NewInput, 0);
					*NewKeyboardController = {};
					NewKeyboardController->IsConnected = true;

					for (int ButtonIndex = 0; ButtonIndex < ArrayCount(NewKeyboardController->Buttons); ++ButtonIndex) {
						NewKeyboardController->Buttons[ButtonIndex].EndedDown = OldKeyboardController->Buttons[ButtonIndex].EndedDown;
					}

					Win32ProcessPendingMessages(&Win32State, NewKeyboardController);

					if (!GlobalPause) {
						POINT MousePoint;
						GetCursorPos(&MousePoint);
						ScreenToClient(Window, &MousePoint);
						NewInput->MouseX = MousePoint.x;
						NewInput->MouseY = MousePoint.y;
						NewInput->MouseZ = 0; // TODO: support mousewheel?
						Win32ProcessKeyboardMessage(&NewInput->MouseButtons[0], GetKeyState(VK_LBUTTON) & (1 << 15));
						Win32ProcessKeyboardMessage(&NewInput->MouseButtons[1], GetKeyState(VK_MBUTTON) & (1 << 15));
						Win32ProcessKeyboardMessage(&NewInput->MouseButtons[2], GetKeyState(VK_RBUTTON) & (1 << 15));
						Win32ProcessKeyboardMessage(&NewInput->MouseButtons[3], GetKeyState(VK_XBUTTON1) & (1 << 15));
						Win32ProcessKeyboardMessage(&NewInput->MouseButtons[4], GetKeyState(VK_XBUTTON2) & (1 << 15));

						// TODO: should we poll this more frequently
						// TODO: dont poll disconnected controllers to prevent xinput frame rate impact
						DWORD MaxControllerCount = XUSER_MAX_COUNT;
						if (MaxControllerCount > (ArrayCount(NewInput->Controllers) - 1)) {
							MaxControllerCount = (ArrayCount(NewInput->Controllers) - 1);
						}

						for (DWORD ControllerIndex = 0; ControllerIndex < MaxControllerCount; ++ControllerIndex) {
							DWORD OurControllerIndex = ControllerIndex + 1;
							game_controller_input *OldController = GetController(OldInput, OurControllerIndex);
							game_controller_input *NewController = GetController(NewInput, OurControllerIndex);

							XINPUT_STATE ControllerState;

							if (XInputGetState(ControllerIndex, &ControllerState) == ERROR_SUCCESS) {
								NewController->IsConnected = true;
								NewController->IsAnalog = OldController->IsAnalog;
								// TODO: See if ControllerState.dwPacketNumber increments too rapidly
								XINPUT_GAMEPAD *Pad = &ControllerState.Gamepad;

								// TODO: currently handling a square deadzone, check if it is circular
								NewController->StickAverageX = Win32ProcessXInputStickValue(Pad->sThumbLX, XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE);
								NewController->StickAverageY = Win32ProcessXInputStickValue(Pad->sThumbLY, XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE);

								if ((NewController->StickAverageX != 0.0f) || (NewController->StickAverageY != 0.0f)) {
									NewController->IsAnalog = true;
								}

								if (Pad->wButtons & XINPUT_GAMEPAD_DPAD_UP) {
									NewController->StickAverageY = 1.0f;
									NewController->IsAnalog = false;
								}

								if (Pad->wButtons & XINPUT_GAMEPAD_DPAD_DOWN) {
									NewController->StickAverageY = -1.0f;
									NewController->IsAnalog = false;
								}

								if (Pad->wButtons & XINPUT_GAMEPAD_DPAD_LEFT) {
									NewController->StickAverageX = -1.0f;
									NewController->IsAnalog = false;
								}

								if (Pad->wButtons & XINPUT_GAMEPAD_DPAD_RIGHT) {
									NewController->StickAverageX = 1.0f;
									NewController->IsAnalog = false;
								}

								real32 Threshold = 0.5f;
								Win32ProcessXInputDigitalButton((NewController->StickAverageX < -Threshold) ? 1 : 0, &OldController->MoveLeft, 1, &NewController->MoveLeft);
								Win32ProcessXInputDigitalButton((NewController->StickAverageX > Threshold) ? 1 : 0, &OldController->MoveRight, 1, &NewController->MoveRight);
								Win32ProcessXInputDigitalButton((NewController->StickAverageY < -Threshold) ? 1 : 0, &OldController->MoveDown, 1, &NewController->MoveDown);
								Win32ProcessXInputDigitalButton((NewController->StickAverageY > Threshold) ? 1 : 0, &OldController->MoveUp, 1, &NewController->MoveUp);

								Win32ProcessXInputDigitalButton(Pad->wButtons, &OldController->ActionDown, XINPUT_GAMEPAD_A, &NewController->ActionDown);
								Win32ProcessXInputDigitalButton(Pad->wButtons, &OldController->ActionRight, XINPUT_GAMEPAD_B, &NewController->ActionRight);
								Win32ProcessXInputDigitalButton(Pad->wButtons, &OldController->ActionLeft, XINPUT_GAMEPAD_X, &NewController->ActionLeft);
								Win32ProcessXInputDigitalButton(Pad->wButtons, &OldController->ActionUp, XINPUT_GAMEPAD_Y, &NewController->ActionUp);
								Win32ProcessXInputDigitalButton(Pad->wButtons, &OldController->LeftShoulder, XINPUT_GAMEPAD_LEFT_SHOULDER, &NewController->LeftShoulder);
								Win32ProcessXInputDigitalButton(Pad->wButtons, &OldController->RightShoulder, XINPUT_GAMEPAD_RIGHT_SHOULDER, &NewController->RightShoulder);

								Win32ProcessXInputDigitalButton(Pad->wButtons, &OldController->Start, XINPUT_GAMEPAD_START, &NewController->Start);
								Win32ProcessXInputDigitalButton(Pad->wButtons, &OldController->Back, XINPUT_GAMEPAD_BACK, &NewController->Back);
							}
							else {
								// NOTE: the controller is not available
								NewController->IsConnected = false;
							}
						}

						thread_context Thread = {};

						game_offscreen_buffer Buffer = {};
						Buffer.Memory = GlobalBackbuffer.Memory;
						Buffer.Width = GlobalBackbuffer.Width;
						Buffer.Height = GlobalBackbuffer.Height;
						Buffer.Pitch = GlobalBackbuffer.Pitch;
						Buffer.BytesPerPixel = GlobalBackbuffer.BytesPerPixel;

						if (Win32State.InputRecordingIndex) {
							Win32RecordInput(&Win32State, NewInput);
						}

						if (Win32State.InputPlaybackIndex) {
							Win32PlaybackInput(&Win32State, NewInput);
						}

						if (Game.UpdateAndRender) {
							Game.UpdateAndRender(&Thread, &GameMemory, NewInput, &Buffer);
						}

						LARGE_INTEGER AudioWallClock = Win32GetWallClock();
						real32 FromBeginToAudioSeconds = Win32GetSecondsElapsed(FlipWallClock, AudioWallClock);

						DWORD PlayCursor;
						DWORD WriteCursor;

						if (GlobalSecondaryBuffer->GetCurrentPosition(&PlayCursor, &WriteCursor) == DS_OK) {
							/* NOTE: Sound output explanation

							We define a safety value that is the number of samples we think our game update loop can vary by.
							When we wake up to write audio we look at the play cursor position and forecast where we think it will be on the next frame boundary.
							If the write cursor is before that by at least our safety value, the target fill position is the frame boundary plus one frame. This gives us perfect audio sync if the audio latency is low enough.
							If the write cursor is after that safety value then we assume we can't sync the audio so we write one frames worth of audio plus the safety values worth of samples.

							*/

							if (!SoundIsValid) {
								SoundOutput.RunningSampleIndex = WriteCursor / SoundOutput.BytesPerSample;
								SoundIsValid = true;
							}

							DWORD ByteToLock = (SoundOutput.RunningSampleIndex * SoundOutput.BytesPerSample) % SoundOutput.SecondaryBufferSize;
							DWORD ExpectedSoundBytesPerFrame = (int)((real32)(SoundOutput.SamplesPerSecond * SoundOutput.BytesPerSample) / GameUpdateHz);
							real32 SecondsLeftUntilFlip = TargetSecondsPerFrame - FromBeginToAudioSeconds;
							DWORD ExpectedBytesUntilFlip = (DWORD)((SecondsLeftUntilFlip / TargetSecondsPerFrame) * (real32)ExpectedSoundBytesPerFrame);
							DWORD ExpectedFrameBoundaryByte = PlayCursor + ExpectedBytesUntilFlip;
							DWORD SafeWriteCursor = WriteCursor;

							if (SafeWriteCursor < PlayCursor) {
								SafeWriteCursor += SoundOutput.SecondaryBufferSize;
							}

							Assert(SafeWriteCursor >= PlayCursor);
							SafeWriteCursor += SoundOutput.SafetyBytes;
							bool32 AudioCardIsLowLatency = (SafeWriteCursor < ExpectedFrameBoundaryByte);
							DWORD TargetCursor = 0;

							if (AudioCardIsLowLatency) {
								TargetCursor = ExpectedFrameBoundaryByte + ExpectedSoundBytesPerFrame;
							}
							else {
								TargetCursor = WriteCursor + ExpectedSoundBytesPerFrame + SoundOutput.SafetyBytes;
							}

							TargetCursor = TargetCursor % SoundOutput.SecondaryBufferSize;
							DWORD BytesToWrite = 0;

							if (ByteToLock > TargetCursor) {
								BytesToWrite = SoundOutput.SecondaryBufferSize - ByteToLock;
								BytesToWrite += TargetCursor;
							}
							else {
								BytesToWrite = TargetCursor - ByteToLock;
							}

							game_sound_output_buffer SoundBuffer = {};
							SoundBuffer.SamplesPerSecond = SoundOutput.SamplesPerSecond;
							SoundBuffer.SampleCount = BytesToWrite / SoundOutput.BytesPerSample;
							SoundBuffer.Samples = Samples;
							if (Game.GetSoundSamples) {
								Game.GetSoundSamples(&Thread, &GameMemory, &SoundBuffer);
							}

#if HANDMADE_INTERNAL
							win32_debug_time_marker *Marker = &DebugTimeMarkers[DebugTimeMarkerIndex];
							Marker->OutputPlayCursor = PlayCursor;
							Marker->OutputWriteCursor = WriteCursor;
							Marker->OutputLocation = ByteToLock;
							Marker->OutputByteCount = BytesToWrite;
							Marker->ExpectedFlipPlayCursor = ExpectedFrameBoundaryByte;
							DWORD UnwrappedWriteCursor = WriteCursor;

							if (UnwrappedWriteCursor < PlayCursor) {
								UnwrappedWriteCursor += SoundOutput.SecondaryBufferSize;
							}

							AudioLatencyBytes = UnwrappedWriteCursor - PlayCursor;
							AudioLatencySeconds = ((real32)AudioLatencyBytes / (real32)SoundOutput.BytesPerSample) / (real32)SoundOutput.SamplesPerSecond;

#if 0
							char DebugSoundBuffer[256];
							sprintf_s(DebugSoundBuffer, "BTL:%u TC:%u BTW:%u - PC:%u WC:%u DELTA:%u (%fs)\n", ByteToLock, TargetCursor, BytesToWrite, PlayCursor, WriteCursor, AudioLatencyBytes, AudioLatencySeconds);
							OutputDebugStringA(DebugSoundBuffer);
#endif
#endif
							Win32FillSoundBuffer(&SoundOutput, ByteToLock, BytesToWrite, &SoundBuffer);
						}
						else {
							SoundIsValid = false;
						}

						LARGE_INTEGER WorkCounter = Win32GetWallClock();
						real32 WorkSecondsElapsed = Win32GetSecondsElapsed(LastCounter, WorkCounter);
						// TODO: not tested yet!
						real32 SecondsElapsedForFrame = WorkSecondsElapsed;

						if (SecondsElapsedForFrame < TargetSecondsPerFrame) {
							if (SleepIsGranular) {
								DWORD SleepMS = (DWORD)(1000.0f * (TargetSecondsPerFrame - SecondsElapsedForFrame));
								if (SleepMS > 0) {
									Sleep(SleepMS);
								}
							}

							real32 TestSecondsElapsedForFrame = Win32GetSecondsElapsed(LastCounter, Win32GetWallClock());

							if (TestSecondsElapsedForFrame < TargetSecondsPerFrame) {
								// TODO: log missed sleep here
							}

							while (SecondsElapsedForFrame < TargetSecondsPerFrame) {
								SecondsElapsedForFrame = Win32GetSecondsElapsed(LastCounter, Win32GetWallClock());
							}
						}
						else {
							// TODO: missed frame rate
							// TODO: logging
						}

						LARGE_INTEGER EndCounter = Win32GetWallClock();
						real32 MSPerFrame = 1000.0f * Win32GetSecondsElapsed(LastCounter, EndCounter);
						LastCounter = EndCounter;

						win32_window_dimension Dimension = Win32GetWindowDimension(Window);
						HDC BufferDC = GetDC(Window);
						Win32DisplayBufferInWindow(&GlobalBackbuffer, BufferDC, Dimension.Width, Dimension.Height);
						ReleaseDC(Window, BufferDC);

						FlipWallClock = Win32GetWallClock();

#if HANDMADE_INTERNAL
						DWORD DebugPlayCursor;
						DWORD DebugWriteCursor;
						if (GlobalSecondaryBuffer->GetCurrentPosition(&DebugPlayCursor, &DebugWriteCursor) == DS_OK) {
							Assert(DebugTimeMarkerIndex < ArrayCount(DebugTimeMarkers));
							win32_debug_time_marker *Marker = &DebugTimeMarkers[DebugTimeMarkerIndex];
							Marker->FlipPlayCursor = DebugPlayCursor;
							Marker->FlipWriteCursor = DebugWriteCursor;
						}
#endif

						game_input *Temp = NewInput;
						NewInput = OldInput;
						OldInput = Temp;
						// TODO: should these be cleared?

#if 0
						uint64 EndCycleCount = __rdtsc();
						uint64 CyclesElapsed = EndCycleCount - LastCycleCount;
						LastCycleCount = EndCycleCount;

						// real32 FPS = (real32)GlobalPerfCounterFrequency / (real32)CounterElapsed;
						real32 FPS = 0.0f;
						real32 MCPF = (real32)CyclesElapsed / (1000.0f * 1000.0f);

						char DebugPerformanceBuffer[256];
						sprintf_s(DebugPerformanceBuffer, "%0.02fmspf, %0.02ffps, %0.02fmcpf\n", MSPerFrame, FPS, MCPF);
						OutputDebugStringA(DebugPerformanceBuffer);
#endif

#if HANDMADE_INTERNAL
						++DebugTimeMarkerIndex;
						if (DebugTimeMarkerIndex == ArrayCount(DebugTimeMarkers)) {
							DebugTimeMarkerIndex = 0;
						}
#endif
					}
				}
			}
			else {
				// TODO: logging
			}
		}
		else {
			// TODO: logging
		}
	}
	else {
		// TODO: logging
	}

	return(0);
}