Problems with GetAsyncKeyState

This is a discussion on Problems with GetAsyncKeyState within the C++ Programming forums, part of the General Programming Boards category; Code: if (GetAsyncKeyState(VK_MENU)) { //do stuff... } else { //do other stuff } This is a camera that can look ...

  1. #1
    Registered User
    Join Date
    Apr 2007
    Posts
    27

    Problems with GetAsyncKeyState

    Code:
    if (GetAsyncKeyState(VK_MENU))
    {
          //do stuff...
    }
    else
    {
          //do other stuff
    }
    This is a camera that can look 360 around the Y, and 90 and -90 up the Y axis, and is meant to do this only when an ALT key is pressed. Other wise (currently) it moves with the mouse Y or X as according to how you are moving the mouse (horizontal when sideways, vertical when forwards).
    This all works great EXCEPT that while it works when I hold alt, it doesn't do ANYTHIGN when I release, but if I hold it again it works fine, then it'll take in mouse signals like it's supposed to. I've tried other suggestions I found responding to someone elses problems with GetAsyncKeyState() on these forums, but it didn't change anything except make it look fancy lol.
    What I need is to hold alt, and it does the if statement, and when I let go of alt, for it to do the else statement. Would it work as a switch (I haven't tried because I doubt it'll change anything according to logic, though that doesn't apply to C++ lol). Any thoughts?


    (Anyone with two cents on how to make it not require a second alt restroke to turn it off and allow my default to happen is appreciated. I've tried macros that "mask" the most significant bit to do this, and I've tried setting it every call (virtually) to being let go, and this simply causes jittery performance from it constantly thinking i'm letting go and then reholding ALT. I am willing to retry these, I'm just stating...)

  2. #2
    Captain - Lover of the C
    Join Date
    May 2005
    Posts
    341
    Try this. If you're getting strange results, the problem is somewhere else in the code. Post the code that does the rotation. The problem might lie there.
    Code:
    if (GetAsyncKeyState(VK_MENU) & 0x8000)
    {
         // The alt key is down.  The problem is not with GetAsyncKeyState
    }
    else
    {
         // The alt key is up.  The problem is not with GetAsyncKeyState
    }
    Don't quote me on that... ...seriously

  3. #3
    Registered User
    Join Date
    Apr 2007
    Posts
    27

    Gr

    I'm reluctant to post my code because all it is is math equations that change the coordinates of the camera position or target. It HAS to be in the use of GetAsyncKeyState(). I will restate the problem (hopefully clearer) so you get that GetAsyncKeyState() is doing what it is supposed to do, I just need a way around it doing that lol.
    When I start, it defaults to the else state ment allowing camera POSITION movement. Hold Alt, and then it goes to if statement as long as alt is held. However, when letting go of alt, it "freezes", but still takes in mouse input, so when you hold alt again, your camera is pointing wherever it would be, as if you had been holding it the whole time, except not animating during this time. After holding alt a second time (or every 2nd time you've used alt to look around) it works as planned, moving camera TARGET while on alt, and camera POSITION while not on alt.
    I tried your idea, and it doesn't seem to work for me. Would it matter at all that I'm in Direct3D? (9.0c to answer that question if it ever came up)

    (The reason for being reluctant to give up that math is because it took a long time to derive it on paper, and to simply post it online so soon, whether a game or two use cameras similar or not, I am too proud to just give everyone who can copy paste my hours of conceptual work, however simple it reduced down to, or obvious to some it might be.)

  4. #4
    Registered User manofsteel972's Avatar
    Join Date
    Mar 2004
    Posts
    317
    According to Microsofts Website for GetAsyncKeyState

    If the function succeeds, the return value specifies whether the key was pressed since the last call to GetAsyncKeyState, and whether the key is currently up or down. If the most significant bit is set, the key is down, and if the least significant bit is set, the key was pressed after the previous call to GetAsyncKeyState
    Brad is right. Unless you have something in your code that blocks execution, it should work. Take the example below.

    Code:
    #include<iostream>
    #include<windows.h>
    int main(void)
    {
    	while(true)
    	{
    		short int test=(GetAsyncKeyState(VK_MENU)&0x8000);
    		
    		if(test)
    		{
    			std::cout<<"Keydown\n";
    		}
    		else
    		{
    			std::cout<<"KeyUp\n";
    		}
    	}
    
    	return 0;
    }
    You could do it as a switch statement.

    Code:
    	switch(GetAsyncKeyState(VK_MENU)&0x8000)
    	{
    	case true:
    		break;
    		
    	case false:
    		break;
    	};
    Last edited by manofsteel972; 04-18-2007 at 02:01 AM.
    "Knowledge is proud that she knows so much; Wisdom is humble that she knows no more."
    -- Cowper

    Operating Systems=Slackware Linux 9.1,Windows 98/Xp
    Compilers=gcc 3.2.3, Visual C++ 6.0, DevC++(Mingw)

    You may teach a person from now until doom's day, but that person will only know what he learns himself.

    Now I know what doesn't work.

    A problem is understood by solving it, not by pondering it.

    For a bit of humor check out xkcd web comic http://xkcd.com/235/

  5. #5
    Captain - Lover of the C
    Join Date
    May 2005
    Posts
    341
    Quote Originally Posted by blurrymadness View Post
    I'm reluctant to post my code because all it is is math equations that change the coordinates of the camera position or target. It HAS to be in the use of GetAsyncKeyState(). I will restate the problem (hopefully clearer) so you get that GetAsyncKeyState() is doing what it is supposed to do, I just need a way around it doing that lol.
    When I start, it defaults to the else state ment allowing camera POSITION movement. Hold Alt, and then it goes to if statement as long as alt is held. However, when letting go of alt, it "freezes", but still takes in mouse input, so when you hold alt again, your camera is pointing wherever it would be, as if you had been holding it the whole time, except not animating during this time. After holding alt a second time (or every 2nd time you've used alt to look around) it works as planned, moving camera TARGET while on alt, and camera POSITION while not on alt.
    I tried your idea, and it doesn't seem to work for me. Would it matter at all that I'm in Direct3D? (9.0c to answer that question if it ever came up)

    (The reason for being reluctant to give up that math is because it took a long time to derive it on paper, and to simply post it online so soon, whether a game or two use cameras similar or not, I am too proud to just give everyone who can copy paste my hours of conceptual work, however simple it reduced down to, or obvious to some it might be.)
    Since you won't post your code, I'll guess. Take a look at your code in the else statement. There must be a variable that gets set and unset somewhere that your else statement checks to update the animation. Here's a simplified example of what I'm guessing is happening:
    Code:
    int UpdateAnimation = 1;
    int SomeOtherVariable = 1;
    if (GetAsyncKeyState(VK_MENU) & 0x8000)
    {
       if (UpdateAnimation)
       {
             SomeOtherVariable = 0;
        }
        else
        {
             SomeOtherVariable = 1;
        }
    }
    else
    {
         UpdateAnimation = SomeOtherVariable;
         if (UpdateAnimation)
         {
               // Update animation
         }
         else
         {
               // confuse the heck out of the programmer
         }
    }
    That's just an example of the logic error that may or may not be happening.
    Don't quote me on that... ...seriously

  6. #6
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    32,854
    > I'm reluctant to post my code because all it is is math equations that change the coordinates of the camera position or target
    Crreate another program which just tests your understanding of GetAsyncKeyState()

    This will either do two things
    1. It will show you exactly where the problem lies, and you can fix it all for yourself.
    2. If you're still stuck, you have a nice simple program you can post to the board which people can look at in the whole and give really specific help.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.
    I support http://www.ukip.org/ as the first necessary step to a free Europe.

  7. #7
    Registered User
    Join Date
    Apr 2007
    Posts
    27

    Hm

    I reduced it to a bare bones camera (no movement. No horizontal or vertical rotation). I believe there's a few things that MIGHT be happening. I scoured the program (I could post it in it's entirety, EXCEPT that it might be a copyright violation, I've been building my camera inside Frank Luna's TriGridDemo.. demo, before moving along in my D3DX book). Anyway, I scoured looking for an ALT or anything, and I didn't find anything. So I was thinking, maybe it's talking to windows or something else when I press it, so it's reverting control to another program. This would make sense (though what the heck switches with JUST alt?) since it stops animating, meaning that maybe it's got something from Visual Studio or something else in the background causing this to happen.

    You see, that would allow control while alt is held because it hasn't been PRESSED yet, it would go to the else statement, HOWEVER whatever it is has switched control, so when you hold it again, the new mouse position is found, recorded, and applied, then continuing to hold makes it work like normal, letting go NOW however, will give you control back, since it's been pressed.

    This is just backwards logic trying to find the problem. I'll post the Direct3D code from Luna that nabs the keyboard, and the functions dealing with said keyboard. I'm sure it's in this, or Visual Studio in general. (I did try messing with the keyDown that he has, thikning that getting rid of that just might (i'm desperate lol) make it so it wouldn't turn the key on and off. I still believe it is transfering control to outside the program).


    Code:
    //=============================================================================
    // DirectInput.cpp by Frank Luna (C) 2005 All Rights Reserved.
    //=============================================================================
    
    #include "d3dUtil.h"
    #include "DirectInput.h"
    #include "d3dApp.h"
    
    DirectInput* gDInput = 0;
    
    DirectInput::DirectInput(DWORD keyboardCoopFlags, DWORD mouseCoopFlags)
    {
    	ZeroMemory(mKeyboardState, sizeof(mKeyboardState));
    	ZeroMemory(&mMouseState, sizeof(mMouseState));
    
    	HR(DirectInput8Create(gd3dApp->getAppInst(), DIRECTINPUT_VERSION, 
    		IID_IDirectInput8, (void**)&mDInput, 0));
    
    	HR(mDInput->CreateDevice(GUID_SysKeyboard, &mKeyboard, 0));
    	HR(mKeyboard->SetDataFormat(&c_dfDIKeyboard));
    	HR(mKeyboard->SetCooperativeLevel(gd3dApp->getMainWnd(), keyboardCoopFlags));
    	HR(mKeyboard->Acquire());
    
    	HR(mDInput->CreateDevice(GUID_SysMouse, &mMouse, 0));
    	HR(mMouse->SetDataFormat(&c_dfDIMouse2));
    	HR(mMouse->SetCooperativeLevel(gd3dApp->getMainWnd(), mouseCoopFlags));
    	HR(mMouse->Acquire());
    }
    
    DirectInput::~DirectInput()
    {
    	ReleaseCOM(mDInput);
    	mKeyboard->Unacquire();
    	mMouse->Unacquire();
    	ReleaseCOM(mKeyboard);
    	ReleaseCOM(mMouse);
    }
    
    void DirectInput::poll()
    {
    	// Poll keyboard.
    	HRESULT hr = mKeyboard->GetDeviceState(sizeof(mKeyboardState), (void**)&mKeyboardState); 
    	if( FAILED(hr) )
    	{
    		// Keyboard lost, zero out keyboard data structure.
    		ZeroMemory(mKeyboardState, sizeof(mKeyboardState));
    
    		 // Try to acquire for next time we poll.
    		hr = mKeyboard->Acquire();
    	}
    
    	// Poll mouse.
    	hr = mMouse->GetDeviceState(sizeof(DIMOUSESTATE2), (void**)&mMouseState); 
    	if( FAILED(hr) )
    	{
    		// Mouse lost, zero out mouse data structure.
    		ZeroMemory(&mMouseState, sizeof(mMouseState));
    
    		// Try to acquire for next time we poll.
    		hr = mMouse->Acquire(); 
    	}
    }
    
    bool DirectInput::keyDown(char key)
    {
    	return (mKeyboardState[key] & 0x80) != 0;
    }
    
    bool DirectInput::mouseButtonDown(int button)
    {
    	return (mMouseState.rgbButtons[button] & 0x80) != 0;
    }
    
    float DirectInput::mouseDX()
    {
    	return (float)mMouseState.lX;
    }
    
    float DirectInput::mouseDY()
    {
    	return (float)mMouseState.lY;
    }
    
    float DirectInput::mouseDZ()
    {
    	return (float)mMouseState.lZ;
    }
    Code:
    //=============================================================================
    // DirectInput.h by Frank Luna (C) 2005 All Rights Reserved.
    //
    // Wraps initialization of immediate mode Direct Input, and provides 
    // information for querying the state of the keyboard and mouse.
    //=============================================================================
    
    #ifndef DIRECT_INPUT_H
    #define DIRECT_INPUT_H
    
    #define DIRECTINPUT_VERSION 0x0800
    #include <dinput.h>
    
    class DirectInput
    {
    public:
    	DirectInput(DWORD keyboardCoopFlags, DWORD mouseCoopFlags);
    	~DirectInput();
    
    	void poll();
    	bool keyDown(char key);
    	bool mouseButtonDown(int button);
    	float mouseDX();
    	float mouseDY();
    	float mouseDZ();
    
    private:
    	// Make private to prevent copying of members of this class.
    	DirectInput(const DirectInput& rhs);
    	DirectInput& operator=(const DirectInput& rhs);
    		
    private:
    	IDirectInput8*       mDInput;
    
    	IDirectInputDevice8* mKeyboard;
    	char                 mKeyboardState[256]; 
    
    	IDirectInputDevice8* mMouse;
    	DIMOUSESTATE2        mMouseState;
    };
    extern DirectInput* gDInput;
    
    #endif // DIRECT_INPUT_H
    (I found these shortcuts for visual studio)

    Press Alt to put focus on the File Menu. <-probably not
    Press Alt and then select the area you want with your mouse. <-seems semi logical?
    Last edited by blurrymadness; 04-18-2007 at 11:25 PM.

  8. #8
    Captain - Lover of the C
    Join Date
    May 2005
    Posts
    341
    Ha ha ha. You wouldn't be windowed by any chance? I wrote a little program to check whether or not you were crazy. Turns out that when you have a window, pressing alt activates the system menu in the upper left corner of the window. This causes your window to not refresh until you hit alt again and close the system menu. If you define WS_POPUP, you won't have this problem.
    Don't quote me on that... ...seriously

  9. #9
    Registered User
    Join Date
    Apr 2007
    Posts
    27
    Quote Originally Posted by Brad0407 View Post
    Ha ha ha. You wouldn't be windowed by any chance? I wrote a little program to check whether or not you were crazy. Turns out that when you have a window, pressing alt activates the system menu in the upper left corner of the window. This causes your window to not refresh until you hit alt again and close the system menu. If you define WS_POPUP, you won't have this problem.

    YES. Thanks. Having trouble still, being that after defining WS_POPUP

    Code:
    #define D3D_FULLSCREEN_STYLE (WS_POPUP)
    It still does the same problem. I am unsure how to use it, (i'm surprised my guide to d3d didn't tell me ANYTHING about it lol). And another thing, it crashes if I try to switch to fullscreen to true (code below)

    Code:
    //=============================================================================
    // d3dApp.h by Frank Luna (C) 2005 All Rights Reserved.
    //=============================================================================
    
    #include "d3dApp.h"
    #define D3D_FULLSCREEN_STYLE (WS_POPUP)
    
    D3DApp* gd3dApp              = 0;
    IDirect3DDevice9* gd3dDevice = 0;
    
    LRESULT CALLBACK
    MainWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
    {
    	// Don't start processing messages until the application has been created.
    	if( gd3dApp != 0 )
    		return gd3dApp->msgProc(msg, wParam, lParam);
    	else
    		return DefWindowProc(hwnd, msg, wParam, lParam);
    }
    
    D3DApp::D3DApp(HINSTANCE hInstance, std::string winCaption, D3DDEVTYPE devType, DWORD requestedVP)
    {
    	mMainWndCaption = winCaption;
    	mDevType        = devType;
    	mRequestedVP    = requestedVP;
    	
    	mhAppInst   = hInstance;
    	mhMainWnd   = 0;
    	md3dObject  = 0;
    	mAppPaused  = false;
    	ZeroMemory(&md3dPP, sizeof(md3dPP));
    
    	initMainWindow();
    	initDirect3D();
    }
    
    D3DApp::~D3DApp()
    {
    	ReleaseCOM(md3dObject);
    	ReleaseCOM(gd3dDevice);
    }
    
    HINSTANCE D3DApp::getAppInst()
    {
    	return mhAppInst;
    }
    
    HWND D3DApp::getMainWnd()
    {
    	return mhMainWnd;
    }
    
    void D3DApp::initMainWindow()
    {
    	WNDCLASS wc;
    	wc.style         = CS_HREDRAW | CS_VREDRAW;
    	wc.lpfnWndProc   = MainWndProc; 
    	wc.cbClsExtra    = 0;
    	wc.cbWndExtra    = 0;
    	wc.hInstance     = mhAppInst;
    	wc.hIcon         = LoadIcon(0, IDI_APPLICATION);
    	wc.hCursor       = LoadCursor(0, IDC_ARROW);
    	wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
    	wc.lpszMenuName  = 0;
    	wc.lpszClassName = "D3DWndClassName";
    
    	if( !RegisterClass(&wc) )
    	{
    		MessageBox(0, "RegisterClass FAILED", 0, 0);
    		PostQuitMessage(0);
    	}
    
    	// Default to a window with a client area rectangle of 800x600.
    
    	RECT R = {0, 0, 800, 600};
    	AdjustWindowRect(&R, WS_OVERLAPPEDWINDOW, false);
    	mhMainWnd = CreateWindow("D3DWndClassName", mMainWndCaption.c_str(), 
    		WS_OVERLAPPEDWINDOW, 100, 100, R.right, R.bottom, 
    		0, 0, mhAppInst, 0); 
    
    	if( !mhMainWnd )
    	{
    		MessageBox(0, "CreateWindow FAILED", 0, 0);
    		PostQuitMessage(0);
    	}
    
    	ShowWindow(mhMainWnd, SW_SHOW);
    	UpdateWindow(mhMainWnd);
    }
    
    void D3DApp::initDirect3D()
    {
    	// Step 1: Create the IDirect3D9 object.
    
        md3dObject = Direct3DCreate9(D3D_SDK_VERSION);
    	if( !md3dObject )
    	{
    		MessageBox(0, "Direct3DCreate9 FAILED", 0, 0);
    		PostQuitMessage(0);
    	}
    
    
    	// Step 2: Verify hardware support for specified formats in windowed and full screen modes.
    	
    	D3DDISPLAYMODE mode;
    	md3dObject->GetAdapterDisplayMode(D3DADAPTER_DEFAULT, &mode);
    	HR(md3dObject->CheckDeviceType(D3DADAPTER_DEFAULT, mDevType, mode.Format, mode.Format, true));
    	HR(md3dObject->CheckDeviceType(D3DADAPTER_DEFAULT, mDevType, D3DFMT_X8R8G8B8, D3DFMT_X8R8G8B8, false));
    
    	// Step 3: Check for requested vertex processing and pure device.
    
    	D3DCAPS9 caps;
    	HR(md3dObject->GetDeviceCaps(D3DADAPTER_DEFAULT, mDevType, &caps));
    
    	DWORD devBehaviorFlags = 0;
    	if( caps.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT )
    		devBehaviorFlags |= mRequestedVP;
    	else
    		devBehaviorFlags |= D3DCREATE_SOFTWARE_VERTEXPROCESSING;
    
    	// If pure device and HW T&L supported
    	if( caps.DevCaps & D3DDEVCAPS_PUREDEVICE &&
    		devBehaviorFlags & D3DCREATE_HARDWARE_VERTEXPROCESSING)
    			devBehaviorFlags |= D3DCREATE_PUREDEVICE;
    
    	// Step 4: Fill out the D3DPRESENT_PARAMETERS structure.
    
    	md3dPP.BackBufferWidth            = 0; 
    	md3dPP.BackBufferHeight           = 0;
    	md3dPP.BackBufferFormat           = D3DFMT_UNKNOWN;
    	md3dPP.BackBufferCount            = 1;
    	md3dPP.MultiSampleType            = D3DMULTISAMPLE_NONE;
    	md3dPP.MultiSampleQuality         = 0;
    	md3dPP.SwapEffect                 = D3DSWAPEFFECT_DISCARD; 
    	md3dPP.hDeviceWindow              = mhMainWnd;
    	md3dPP.Windowed                   = true;
    	md3dPP.EnableAutoDepthStencil     = true; 
    	md3dPP.AutoDepthStencilFormat     = D3DFMT_D24S8;
    	md3dPP.Flags                      = 0;
    	md3dPP.FullScreen_RefreshRateInHz = D3DPRESENT_RATE_DEFAULT;
    	md3dPP.PresentationInterval       = D3DPRESENT_INTERVAL_IMMEDIATE;
    
    
    	// Step 5: Create the device.
    
    	HR(md3dObject->CreateDevice(
    		D3DADAPTER_DEFAULT, // primary adapter
    		mDevType,           // device type
    		mhMainWnd,          // window associated with device
    		devBehaviorFlags,   // vertex processing
    	    &md3dPP,            // present parameters
    	    &gd3dDevice));      // return created device
    }
    
    int D3DApp::run()
    {
    	MSG  msg;
        msg.message = WM_NULL;
    
    	__int64 cntsPerSec = 0;
    	QueryPerformanceFrequency((LARGE_INTEGER*)&cntsPerSec);
    	float secsPerCnt = 1.0f / (float)cntsPerSec;
    
    	__int64 prevTimeStamp = 0;
    	QueryPerformanceCounter((LARGE_INTEGER*)&prevTimeStamp);
    
    	while(msg.message != WM_QUIT)
    	{
    		// If there are Window messages then process them.
    		if(PeekMessage( &msg, 0, 0, 0, PM_REMOVE ))
    		{
                TranslateMessage( &msg );
                DispatchMessage( &msg );
    		}
    		// Otherwise, do animation/game stuff.
    		else
            {	
    			// If the application is paused then free some CPU cycles to other 
    			// applications and then continue on to the next frame.
    			if( mAppPaused )
    			{
    				Sleep(20);
    				continue;
    			}
    
    			if( !isDeviceLost() )
    			{
    				__int64 currTimeStamp = 0;
    				QueryPerformanceCounter((LARGE_INTEGER*)&currTimeStamp);
    				float dt = (currTimeStamp - prevTimeStamp)*secsPerCnt;
    
    				updateScene(dt);
    				drawScene();
    
    				// Prepare for next iteration: The current time stamp becomes
    				// the previous time stamp for the next iteration.
    				prevTimeStamp = currTimeStamp;
    			}
            }
        }
    	return (int)msg.wParam;
    }
    
    LRESULT D3DApp::msgProc(UINT msg, WPARAM wParam, LPARAM lParam)
    {
    	// Is the application in a minimized or maximized state?
    	static bool minOrMaxed = false;
    
    	RECT clientRect = {0, 0, 0, 0};
    	switch( msg )
    	{
    
    	// WM_ACTIVE is sent when the window is activated or deactivated.
    	// We pause the game when the main window is deactivated and 
    	// unpause it when it becomes active.
    	case WM_ACTIVATE:
    		if( LOWORD(wParam) == WA_INACTIVE )
    			mAppPaused = true;
    		else
    			mAppPaused = false;
    		return 0;
    
    
    	// WM_SIZE is sent when the user resizes the window.  
    	case WM_SIZE:
    		if( gd3dDevice )
    		{
    			md3dPP.BackBufferWidth  = LOWORD(lParam);
    			md3dPP.BackBufferHeight = HIWORD(lParam);
    
    			if( wParam == SIZE_MINIMIZED )
    			{
    				mAppPaused = true;
    				minOrMaxed = true;
    			}
    			else if( wParam == SIZE_MAXIMIZED )
    			{
    				mAppPaused = false;
    				minOrMaxed = true;
    				onLostDevice();
    				HR(gd3dDevice->Reset(&md3dPP));
    				onResetDevice();
    			}
    			// Restored is any resize that is not a minimize or maximize.
    			// For example, restoring the window to its default size
    			// after a minimize or maximize, or from dragging the resize
    			// bars.
    			else if( wParam == SIZE_RESTORED )
    			{
    				mAppPaused = false;
    
    				// Are we restoring from a mimimized or maximized state, 
    				// and are in windowed mode?  Do not execute this code if 
    				// we are restoring to full screen mode.
    				if( minOrMaxed && md3dPP.Windowed )
    				{
    					onLostDevice();
    					HR(gd3dDevice->Reset(&md3dPP));
    					onResetDevice();
    				}
    				else
    				{
    					// No, which implies the user is resizing by dragging
    					// the resize bars.  However, we do not reset the device
    					// here because as the user continuously drags the resize
    					// bars, a stream of WM_SIZE messages is sent to the window,
    					// and it would be pointless (and slow) to reset for each
    					// WM_SIZE message received from dragging the resize bars.
    					// So instead, we reset after the user is done resizing the
    					// window and releases the resize bars, which sends a
    					// WM_EXITSIZEMOVE message.
    				}
    				minOrMaxed = false;
    			}
    		}
    		return 0;
    
    
    	// WM_EXITSIZEMOVE is sent when the user releases the resize bars.
    	// Here we reset everything based on the new window dimensions.
    	case WM_EXITSIZEMOVE:
    		GetClientRect(mhMainWnd, &clientRect);
    		md3dPP.BackBufferWidth  = clientRect.right;
    		md3dPP.BackBufferHeight = clientRect.bottom;
    		onLostDevice();
    		HR(gd3dDevice->Reset(&md3dPP));
    		onResetDevice();
    
    		return 0;
    
    	// WM_CLOSE is sent when the user presses the 'X' button in the
    	// caption bar menu.
    	case WM_CLOSE:
    		DestroyWindow(mhMainWnd);
    		return 0;
    
    	// WM_DESTROY is sent when the window is being destroyed.
    	case WM_DESTROY:
    		PostQuitMessage(0);
    		return 0;
    
    	case WM_KEYDOWN:
    		if( wParam == VK_ESCAPE )
    			enableFullScreenMode(false);
    		else if( wParam == 'F' )
    			enableFullScreenMode(true);
    		return 0;
    	}
    	return DefWindowProc(mhMainWnd, msg, wParam, lParam);
    }
    
    void D3DApp::enableFullScreenMode(bool enable)
    {
    	// Switch to fullscreen mode.
    	if( enable )
    	{
    		// Are we already in fullscreen mode?
    		if( !md3dPP.Windowed ) 
    			return;
    
    		int width  = GetSystemMetrics(SM_CXSCREEN);
    		int height = GetSystemMetrics(SM_CYSCREEN);
    
    		md3dPP.BackBufferFormat = D3DFMT_X8R8G8B8;
    		md3dPP.BackBufferWidth  = width;
    		md3dPP.BackBufferHeight = height;
    		md3dPP.Windowed         = false;
    
    		// Change the window style to a more fullscreen friendly style.
    		SetWindowLongPtr(mhMainWnd, GWL_STYLE, WS_POPUP);
    
    		// If we call SetWindowLongPtr, MSDN states that we need to call
    		// SetWindowPos for the change to take effect.  In addition, we 
    		// need to call this function anyway to update the window dimensions.
    		SetWindowPos(mhMainWnd, HWND_TOP, 0, 0, width, height, SWP_NOZORDER | SWP_SHOWWINDOW);	
    	}
    	// Switch to windowed mode.
    	else
    	{
    		// Are we already in windowed mode?
    		if( md3dPP.Windowed ) 
    			return;
    
    		RECT R = {0, 0, 800, 600};
    		AdjustWindowRect(&R, WS_OVERLAPPEDWINDOW, false);
    		md3dPP.BackBufferFormat = D3DFMT_UNKNOWN;
    		md3dPP.BackBufferWidth  = 800;
    		md3dPP.BackBufferHeight = 600;
    		md3dPP.Windowed         = true;
    	
    		// Change the window style to a more windowed friendly style.
    		SetWindowLongPtr(mhMainWnd, GWL_STYLE, WS_OVERLAPPEDWINDOW);
    
    		// If we call SetWindowLongPtr, MSDN states that we need to call
    		// SetWindowPos for the change to take effect.  In addition, we 
    		// need to call this function anyway to update the window dimensions.
    		SetWindowPos(mhMainWnd, HWND_TOP, 100, 100, R.right, R.bottom, SWP_NOZORDER | SWP_SHOWWINDOW);
    	}
    
    	// Reset the device with the changes.
    	onLostDevice();
    	HR(gd3dDevice->Reset(&md3dPP));
    	onResetDevice();
    }
    
    bool D3DApp::isDeviceLost()
    {
    	// Get the state of the graphics device.
    	HRESULT hr = gd3dDevice->TestCooperativeLevel();
    
    	// If the device is lost and cannot be reset yet then
    	// sleep for a bit and we'll try again on the next 
    	// message loop cycle.
    	if( hr == D3DERR_DEVICELOST )
    	{
    		Sleep(20);
    		return true;
    	}
    	// Driver error, exit.
    	else if( hr == D3DERR_DRIVERINTERNALERROR )
    	{
    		MessageBox(0, "Internal Driver Error...Exiting", 0, 0);
    		PostQuitMessage(0);
    		return true;
    	}
    	// The device is lost but we can reset and restore it.
    	else if( hr == D3DERR_DEVICENOTRESET )
    	{
    		onLostDevice();
    		HR(gd3dDevice->Reset(&md3dPP));
    		onResetDevice();
    		return false;
    	}
    	else
    		return false;
    }
    p.s. I have* done all this myself at one point, but I ended up modifying the wrong camera, so I continued in his since my first objective is to finish and polish my RTS style camera. Essentially my question is how do I use (is it still called invoking) WS_POPUP to effect, and why does it crash on fullscreen?
    (p.p.s.I hope that this isn't too horrible being as it is a mingling of C, C++, and DirectX. He writes code different than I would prefer to, but its fine for testing my camera!)

  10. #10
    Captain - Lover of the C
    Join Date
    May 2005
    Posts
    341
    You don't need to make the program fullscreen to use WS_POPUP. WS_POPUP will create a window without a border, without a system menu, and most importantly for you, without the title bar. Of course, it's perfectly fine to use fullscreen if you want to but I don't think you are setting up Direct3D properly for your fullscreen mode.
    Don't quote me on that... ...seriously

  11. #11
    Registered User
    Join Date
    Apr 2007
    Posts
    27
    I understand that much. When I defined WS_POPUP at the top, nothing changed, so I'm assuming I need to call it somewhere (even though that sounds wrong to me). At any rate, I defined it as shown above, and it reacts the exact same way, so there's something I'm missing about it. I don't mean to become a nuicence with this, but it's just not working for some reason.

  12. #12
    Captain - Lover of the C
    Join Date
    May 2005
    Posts
    341
    You have 2 modes, windowed and fullscreen. Your fullscreen mode should be WS_POPUP anyway but you can make your windowed mode WS_POPUP also. Changing it at the top only affected your fullscreen mode.
    Don't quote me on that... ...seriously

  13. #13
    Registered User
    Join Date
    Apr 2007
    Posts
    27
    Code:
    	RECT R = {0, 0, 800, 600};
    	AdjustWindowRect(&R, WS_OVERLAPPEDWINDOW, false);
    	mhMainWnd = CreateWindow("D3DWndClassName", mMainWndCaption.c_str(), 
    		WS_OVERLAPPEDWINDOW, 100, 100, R.right, R.bottom, 
    		0, 0, mhAppInst, 0);
    See where it says overlappedwindow? I did some searching and found something that inspired some more reversed logic and I figured out what function to look for, found that, and changed it to

    Code:
    	RECT R = {0, 0, 800, 600};
    	AdjustWindowRect(&R, WS_POPUP, false);
    	mhMainWnd = CreateWindow("D3DWndClassName", mMainWndCaption.c_str(), 
    		WS_MAXIMIZE, 100, 100, R.right, R.bottom, 
    		0, 0, mhAppInst, 0);
    I'm still trying to figure out how to make the full screen work. I can get the it to maximize on its own (now that it's popup, it needs to), but the last kink is it still has that colored bar at the top telling you its name. Do you happen to know how to get rid of that, I'll be searching microsoft's list of things some more, and post my findings, but if you already know, post if I haven't. Thanks for the help. I should've known since it said full screen it wouldn't work for windowed... but it's already defined in direct 3d anyway... but knowing what to look for eventually led to me solving this, thanks for figuring out that menu bar thing!

    Erich

  14. #14
    Registered User
    Join Date
    Apr 2007
    Posts
    27

    Exclamation

    IT IS ALL FIXED. I had to change some stuff after the code. It looks like this...


    These are global variables since the next two code segments are in different areas, I'll probably get around to changing this later, but I figured, "why the same thing twice?" But I COULD just put the actual functions into the parameters I'm sure. We'll just see what happens.
    Code:
    int width  = GetSystemMetrics(SM_CXSCREEN);
    int height = GetSystemMetrics(SM_CYSCREEN);
    This one could probably be more efficient, but as for right now, the latter statements override the previous statements when they run, so it works, but probably isn't the most efficient. (Being that it only runs once, I don't see this as a big deal except for prettiness).
    Code:
    	RECT R = {0, 0, 800, 600};
    	AdjustWindowRect(&R, WS_POPUP, false);
    	mhMainWnd = CreateWindow("D3DWndClassName", mMainWndCaption.c_str(), 
    		WS_MAXIMIZE, 100, 100, R.right, R.bottom, 
    		0, 0, mhAppInst, 0); 
    
    	SetWindowLongPtr(mhMainWnd, GWL_STYLE, WS_POPUP);
    	SetWindowPos(mhMainWnd, HWND_TOP, 0, 0, width, height, SWP_NOZORDER | SWP_SHOWWINDOW);

    Code:
    	md3dPP.BackBufferWidth            = width; 
    	md3dPP.BackBufferHeight           = height;
    	md3dPP.BackBufferFormat           = D3DFMT_X8R8G8B8;
    	md3dPP.BackBufferCount            = 1;
    	md3dPP.MultiSampleType            = D3DMULTISAMPLE_NONE;
    	md3dPP.MultiSampleQuality         = 0;
    	md3dPP.SwapEffect                 = D3DSWAPEFFECT_DISCARD; 
    	md3dPP.hDeviceWindow              = mhMainWnd;
    	md3dPP.Windowed                   = false;
    	md3dPP.EnableAutoDepthStencil     = true; 
    	md3dPP.AutoDepthStencilFormat     = D3DFMT_D24S8;
    	md3dPP.Flags                      = 0;
    	md3dPP.FullScreen_RefreshRateInHz = D3DPRESENT_RATE_DEFAULT;
    	md3dPP.PresentationInterval       = D3DPRESENT_INTERVAL_IMMEDIATE;
    And that's it. Its full screen, no more problems with getAsync...() since it always worked, it was just the stupid system menu! Thanks for the help, and I hope some game developer in his early stages gets use out of this. If anyone wants to tell me to refine the code, I'm happy to listen, otherwise, if they know how, tell the admins or moderators they can lock this down. Probably good for the archives or the FAQ!

    (that looked like all the happy smilies I could get lol)

    Thanks again!!

    Erich

    p.s. I'm not opposed to informing how to do such an RTS camera, but I won't publicly post, or fully give the source, I'll tell you how I used polar coordinates and such.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. No clue how to make a code to solve problems!
    By ctnzn in forum C Programming
    Replies: 8
    Last Post: 10-16-2008, 03:59 AM
  2. Problems with cin and GetAsyncKeyState
    By KgNe in forum C++ Programming
    Replies: 32
    Last Post: 08-21-2008, 11:00 AM
  3. C Pointers Problems
    By mhelal in forum C Programming
    Replies: 8
    Last Post: 01-10-2007, 06:35 AM
  4. Rendering problems (DirectX?)
    By OnionKnight in forum Tech Board
    Replies: 0
    Last Post: 08-17-2006, 01:17 PM
  5. contest problems on my site
    By DavidP in forum Contests Board
    Replies: 4
    Last Post: 01-10-2004, 09:19 PM

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21