NumberKruncher

Hi,

I posted this question in the C# forms forum area a couple of days ago, and I thought perhaps this was a more relevant forum for the question.

I am creating a program which uses the secondary attached monitor. The program successfully creates a Direct3D enabled window which runs fullscreen on the secondary adapter (using an adapter id of 1). This does in fact work smoothly and how I would have expected.

However, there is a serous flaw which I cannot resolve. If something is clicked on the primary monitor (anything at all), the Direct3D enabled window on the secondary devices is minimized immediately (and naturally the DeviceLostException occurs due to the window being minimized).

Somehow I need to stop the program from automatically minimizing, when activitiy occurs outside of the application itself.

Many thanks,

Lea Hayes



Re: Game Technologies: Graphics C# - Managed DirectX - Secondary Monitor

r3n

For debugging, it's handy to have the 2nd adapter so that it doesn't loose focus with the attached window. I have a handy bit of code that changes the render method depending on whether I'm debugging or not.

But remember, you should always handle the DeviceLostException appropriately so that the application does not crash when in a production environment.

#if DEBUG

// Run in while loop mode (better for debugging).
using (Game game = new Game())
{
  while (!game.Exit) { game.Render(); }
}

#else

// Run in invalidate/paint mode (more efficient).
Application.Run(new Game());

#endif





Re: Game Technologies: Graphics C# - Managed DirectX - Secondary Monitor

NumberKruncher

Hi,

Thanks for your reply.

The problem I have isn't so much with debugging, because it does run on the seperate monitors. But, if for example with code similar to that you have suggested, I do enter a breakpoint in Visual Studio...even though shown on the seperate adapter it still minimizes when running in fullscreen mode.

I can have the DX device initialised to run in window mode (which appears fullscreen, with removed borders and controlbox)...but it performs too slow. When running fullscreen it performs fine, but the end-user cannot use Microsoft Access (or any other program) whilst the DX device is shown on the second device (in fullscreen mode).

Somehow I need to get my program to run fullscreen, whilst allowing the user to interact with Windows on the primary monitor. The program I am creating is not directly interactive in anyway, and never actually requires keyboard or mouse focus. It acts as an output for and Access database, and automatically recognises when changes have been made. This part works fine.

There is something in the DirectX SDK which is forcing itself to minimize when something happens outside. The same effect happens in commercial games, so if you were to have a game running on one monitor and outlook on another. Clicking on an email in outlook would cause the game to minimize. Usually this is understanbable, but in my program I need to allow the user to work on device 0 whilst my program does its own thing on device 1.

Thanks again,

Lea Hayes





Re: Game Technologies: Graphics C# - Managed DirectX - Secondary Monitor

r3n

 NumberKruncher wrote:
Somehow I need to get my program to run fullscreen, whilst allowing the user to interact with Windows on the primary monitor.

The code supplied (within #if DEBUG) will do exactly that.





Re: Game Technologies: Graphics C# - Managed DirectX - Secondary Monitor

NumberKruncher

Hi,

Interesting, I removed Application.DoEvents() and now it's working like you have suggested.

My apologies, I didn't realise that it was the windows messages which were causing the problem!

I know it is using Visual C++, but is there a way in C# to filter out certain messages A kind of C# version of WndProc or PretranslateMessage in MFC.

Many thanks for your help!

Lea Hayes





Re: Game Technologies: Graphics C# - Managed DirectX - Secondary Monitor

r3n

C# Form objects have a virtual WndProc method which you can override.

protected override void WndProc(ref Message m)
{
base.WndProc(ref m);
}





Re: Game Technologies: Graphics C# - Managed DirectX - Secondary Monitor

NumberKruncher

Hi,

Excellent! That is exactly what I needed!!
Blocking just the WM_NCACTIVATE message solves the problem.

Many thanks,

Lea Hayes





Re: Game Technologies: Graphics C# - Managed DirectX - Secondary Monitor

r3n

In some situations, using ShowDialog can be better than Application.Run() because then you can start multiple message loops within the same thread. This can be handy if your application needs to automatically restart it's self, and you can't use Application.Restart() for whatever reason.

#if DEBUG
// Run in while loop mode (better for debugging).
using (world = new World(screenList, contentPath))
{
while (!world.Exit) { world.Action(); }
}
#else
// Run in invalidate/paint mode (more efficient).
world = new World(screenList, contentPath);
world.ShowDialog();
#endif





Re: Game Technologies: Graphics C# - Managed DirectX - Secondary Monitor

r3n

Lea,

Do you notice any difference when you block SC_MINIMIZE It would be interesting to find out which is the best approach.

protected override void WndProc(ref Message m)
{
#if DEBUG
const UInt32 WM_SYSCOMMAND = 0x112;
const UInt32 SC_MINIMIZE = 0xF020;
if ((m.Msg == WM_SYSCOMMAND) && ((UInt32)m.WParam == SC_MINIMIZE))
{
return;
}
#endif
base.WndProc(ref m);
}





Re: Game Technologies: Graphics C# - Managed DirectX - Secondary Monitor

NumberKruncher

Hi,

I tried blocking the WM_SYSCOMMAND message as opposed to the WM_NCACTIVATE command; sadly that did not work. I used the Microsoft Spy program (that is shipped with Visual C++), and it did not appear to detect that message; it did however detect the troublesome WM_NCACTIVATE message before abruptly minimizing my app.

However, thankfully the initial approach which you suggested is working great.

Thankyou very much for your suggestions.

Lea





Re: Game Technologies: Graphics C# - Managed DirectX - Secondary Monitor

r3n

Ah, actually that last bit of code I posted didn't work so well afterall.

However, when I trap WM_NCACTIVATE it seems to work nicely!

// Stop strange random minimize issue.
const UInt32 WM_NCACTIVATE = 0x86;
if (m.Msg == WM_NCACTIVATE)
{
return;
}





Re: Game Technologies: Graphics C# - Managed DirectX - Secondary Monitor

NumberKruncher

The only problem I've found with doing that is, if a message box is shown, it is impossible to click its buttons. But apart from that, this approach is working fine.





Re: Game Technologies: Graphics C# - Managed DirectX - Secondary Monitor

r3n

Hmm, I had that problem. But it seemed to go away when I did:

this.Hide();

Cursor.Show();

I'm using Windows.Forms.Form by the way.





Re: Game Technologies: Graphics C# - Managed DirectX - Secondary Monitor

The ZMan

It can't be done. This is how DirectX works. I'm not sure if its changed in DX10 but in DX9 you cannot have a full screen app running and give focus to something else.

(OK so I read the whole thread now... ignoring all windows messages is never a good idea in a production app... interesting one about igrnoign certain messages but won't this cause problems with things like 'show desktop', 'shutdown' or 'hibernate')

The usual workaround is to fake fullscreen on the second monitor by creating a fullscreen window with no borders and making it top most. For all intents and purposes its the same thing.






Re: Game Technologies: Graphics C# - Managed DirectX - Secondary Monitor

NumberKruncher

Hi,

Surely hardware modes are used on the video card when in fullscreen mode. This does appear to have an impact on performance. Yes I do agree that ignoring windows messages is not the ideal solution. Windowed mode does not function as efficiently.

Does anybody know the types of device changes which occur in the background. Perhaps the program could enforce these changes independantly from DirectX, where windowed mode could be used. If this were done it could potentially remove the need to ignore windows messages. I would imagine this would be too low level for C# and would probably need to be written in C++/assembly within a DLL. But this isnt really the path I had intended to chose, due to its low level programming approach.

The problem is not so much because I am unable to use those languages, instead because the people who will be working to maintain the language will not necessarily have such understandings.

Regards,

Lea Hayes