Entries for tag "windows", ordered from most recent. Entry count: 55.
# How to change display mode using WinAPI?
Sat
11
Mar 2017
If you write a graphics application or a game, you may want to make it fullscreen and set specific screen resolution. In DirectX there are functions for that, but if you use OpenGL or Vulkan, you need another way to accomplish that. I've researched the topic recently and I've found that Windows API supports enumerating display devices and modes with functions: EnumDisplayDevices, EnumDisplaySettings, as well as changing mode with function ChangeDisplaySettingsEx. It's a programatic access to more or less the same set of features that you can access manually by going to "Display settings" system window.
I've prepared an example C program demonstrating how to use these functions:
DisplaySettingsTest - github.com/sawickiap
First you may want to enumerate available Adapters. To do this, call function EnumDisplayDevices multiple times. Pass NULL as first parameter (LPCWSTR lpDevice). As the second parameter pass subsequent DWORD Adapter index, starting from 0. Enumeration should continue as long as the function returns BOOL nonzero. When it returns zero, it means there are no more Adapters and that Adapter with given index and any higher index could not be retrieved.
For each successfully retrieved Adapter, DISPLAY_DEVICE structure is filled by the function. It contains following members:
WCHAR DeviceName[32] - string with name of the Adapter, like "\\.\DISPLAY1".WCHAR DeviceString[128] - string with more user-friendly name of the Adapter, like "AMD Radeon (TM) RX 480".DWORD StateFlags - various flags, like DISPLAY_DEVICE_ACTIVE if the device is on, or DISPLAY_DEVICE_PRIMARY_DEVICE if this is the primary device.There is a second level: Adapters contain Display Devices. To enumerate them, use the same function EnumDisplayDevices, but this time pass Adapter DeviceName as first parameter. This way you will enumerate Display Devices inside that Adapter, described by the same structure DISPLAY_DEVICE. For example, my system returns DeviceName = "\\.\DISPLAY1\Monitor0", DeviceString = "Generic PnP Monitor".
The meaning and the difference between "Adapter" and "Display Device" is not fully clear to me. You may think that Adapter is a single GPU (graphics card), but it turns out not to be the case. I have a single graphics card and yet my system reports 6 Adapters, each having 0 or 1 Display Device. That can mean Adapter is more like a single monitor output (e.g. HDMI, DisplayPort, VGA) on the graphics card. This seems true unless you have two monitors running in "Duplicate" mode - then two Display Devices are reported inside one Adapter.
Then there is a list of supported Display Settings (or Modes). You can enumerate them in similar fashion using EnumDisplaySettings function, which fills DEVMODE structure. It seems that Modes belong to an Adapter, not a Display Device, so as first parameter to this function you must to pass DISPLAY_DEVICE::DeviceName returned by EnumDisplayDevices(NULL, ...), not EnumDisplaySettings(adapter.DeviceName, ...). The structure is quite complex, but the function fills only following members:
DWORD dmPelsWidth, dmPelsHeight - resolution, in pixels.DWORD dmBitsPerPel - bits per pixel (all Modes have 32 in my case).DWORD dmDisplayFrequency - refresh rate, in Hz.DWORD dmDisplayFlags - additional flags, like DM_INTERLACED for interlaced mode.I have a single graphics card (AMD Radeon RX 480) with two Full HD (1920 x 1080) monitors connected. You can see example output of the program from my system here: ExampleOutput.txt.
To change display mode, use function ChangeDisplaySettingsEx.
LPCTSTR lpszDeviceName), pass DeviceName of the chosen Adapter (again, not Display Device!).DEVMODE *lpDevMode), pass structure filled with desired Display Settings. You can fill it by yourself, but Microsoft recommends to pass the copy of the structure as it was retrieved from function EnumDisplaySettings.DWORD dwFlags), you can pass various flags, e.g. whether new settings should be saved in the registry.The function returns DISP_CHANGE_SUCCESSFUL if display mode was successfully changed and one of other DISP_CHANGE_* constants if it failed.
To restore original display mode, call the function like this:
ChangeDisplaySettingsEx(targetDeviceName, NULL, NULL, 0, NULL);
Unfortunately, display mode changed in the way described here is not automatically restored after user switches to some other application (e.g. using Alt+Tab), like in DirectX fullscreen mode, but you can handle it yourself. Good news is that if you pass CDS_FULLSCREEN flag to ChangeDisplaySettingsEx, the previous mode is automatically restored by the system when your application exits or crashes.
Comments | #windows #graphics Share
# Handy Global Hotkeys for Music Control
Sat
28
Jan 2017
I now have a keyboard without "media" keys, so I came up with a set of global hotkeys that I've set up in my music player and consider quite handy. ("Global" means they work in the entire system, also when player application is not in focus.) I can't remember where do they come from, but I think it's possible that I've seen them somewhere. These are:

My favorite music player is foobar2000. To setup new global hotkeys there:
I'm sure you can do this in other music players as well, like AIMP.
Comments | #music #windows Share
# 32-bit Applications on 64-bit Windows
Wed
30
Nov 2016
As you probably know, the processor, operating system and applications on a PC may be 32-bit or 64-bit. CPU-s we have in our computers are 64-bit for a long time already. Windows XP tended to be used in 32-bit version, but now I can see most people use Windows 7/8/8.1/10 in 64-bit version as well. Only apps still exist in various forms. Shell extensions and drivers must match the version of the operating system, but other programs can be used in 32-bit version even on 64-bit system. Different combinations are possible:
We may ask a question about where does Windows store files and settings of such apps. It is especially interesting as the answer is very counter-intuitive. Location for (2) – 64-bit apps on 64-bit Windows – may contain “32” in its name (because of backward compatibility), while location for (3) – 32-bit apps on 64-bit Windows – may contain “64” (because of the name WoW64). Here is the list of such locations:
Program Files folder:
System folder:
Registry key:
(Same applies to HKEY_CURRENT_USER.)
See also: Windows 64-bit: The 'Program Files (x86)' and 'SysWOW64' folders explained
# Upgrade to Windows 10 - My Story
Wed
20
Jul 2016
I upgraded my system to Windows 10. Free upgrade is avaiable until July 28th for all genuine users of Windows 7, 8 and 8.1, so now it's high time to do it if you don't want to pay for it later. My upgrade went well, but not without problems. Here is my story:
First some basic information:
On my old Toshiba laptop with Windows 7, bought in 2011, the upgrade failed. The system is not broken though - Windows 7 still works. After the failure I checked manufacturer's website and found that there are no drivers for this model for any operating system newer than Windows 7, so it's good to stay this way.
On my new Lenovo laptop with Windows 8.1, bought in 2015, I was able to successfully perform the upgrade suggested by the system. All the devices work correctly. All installed programs and settings are also preserved.
On my PC, with most components bought in 2013, upgrade to Windows 10 also failed. I can remember fighting with this annoying upgrade window and deleting some system files few months ago, so that might be the reason. I was ready to format my system disk and install everything from scratch anyway, so here is what I did:
I could find drivers for Windows 10 for all my components and peripherals and they all work correctly (except only an old, little webcam - ModeCom MC-1.3M, but I don't use it anyway). I could also install all the programs that I need and they seem to work.
I recommend you to also get your free upgrade to Windows 10. I had an opportunity to work with this system a lot and I could say it's not that bad :) I know there are some arguments against the new Windows version, so let's look at them:
There are some advantages of the new Windows as well, especially compared to Windows 8.x. There is no Charms Bar and Hot Corners when you but your mouse cursor in the corner of the screen. Start Menu is back with just few tiles you can configure and the old good list of installed applications. (You can always get even more old-fashioned Start Menu by installing free app: Classic Shell).
But the most important is what's not visible to the naked eye. As a developer I know that a new operating system is not about new looks of buttons and menus or new Calc application, but mostly about new technologies under the hood. Some of them (like Direct3D 12 and WDDM 2.0, to name just these related to graphics) are available in Windows 10 only. Some applications and games will require them to work sooner or later. That's the reason I believe it's worth upgrading to Windows 10 as long as it's free.
I plan to update my blog more often now, so I invite you to come back here from time to time or subscribe to my RSS channel.
Comments | #microsoft #windows Share
# DirectX 12: What We Already Know?
Wed
03
Jun 2015
I am very excited about the upcoming DirectX 12. I have always been standing on the side of PC, Windows and DirectX. Currently I code in DirectX 11 on Windows 7 at home. Upcoming Windows 10 with free upgrade from version 7 and 8 (and the Start menu back on its place) looks like a good system. Together with it, a new version of DirectX will be released. Let us summarize general information about this new graphics API that are publicly available at the moment.
Here are some interesting links:
First and foremost: Direct3D 12 Graphics @ msdn.microsoft.com. Microsoft says "these information relate to pre-released product and may be substantially modified before it's commercially released", but you can already find there all Direct3D 12 Programming Guide and Reference, so basically the whole API is already public and you can start learning it.
Social Media:
General information:
Slides and videos from conferences:
Videos and screenshots from some working applications already shown:
Comments | #windows #directx Share
# How to Run Windows Command with Given Working Directory?
Sun
27
May 2012
The concept of "working directory" during program startup or "current directory" of the running process is an interesting topic in itself. Maybe I'll write another time about how to manipulate it in different programming languages. This time enough to say that some programs look for auxilliary files in working directory, some in the directory where own EXE file is located and some in other places like user's profile directory.
Problems begin when a program needs auxilliary files located in same directory as executable, but uses working directory to locate it. Apparently such program expects to always be ran with working directory equal to path of its EXE. It happened to me yesterday while using Windows port of Bison (parser generator). Error was:
win_bison: cannot open file `data/m4sugar/m4sugar.m4': No such file or directory
I can't just run the program with another working directory because I execute it from Visual C++, as a Custom Build Tool associated with my ".y" file. There is only place to enter a command in file property page, no place to change working directory, which is by default the directory of Visual C++ project I think.
The solution I found to be able to run a console command with given parameters and also with given working directory is to do it indirectly, using system "start" command, like this:
start /B /WAIT /D <WorkingDir> <ExePath> <Parameters>
Update 2012-11-29: I was informed that the problem in win_bison is now fixed so it can be used without such workaround.
Comments | #visual studio #windows Share
# jEdit Doesn't Start
Sun
30
Oct 2011
jEdit is a free, multi-platform and my favorite text editor intended for programmers. Some time ago I encountered a problem with it, which repeated again today. So in case you also use this editor or found this post by searching Google, here is the solution:
Problem: jEdit (on Windows) doesn't start. Process is created and exists in memory, but it does nothing and shows no windows, so the only thing you can do is terminating it.
Solution: Terminate the jEdit process and the process of Java virtual machine, then browse to your user directory (like "C:\Users\Adam Sawicki" on my Windows 7) and delete the following small file in a sudirectory: ".jedit\server". After that you will be able to successfully start jEdit.
Comments | #java #tools #windows Share
# Handling Ctrl+C in Windows Console Application
Wed
28
Sep 2011
Just a small code snippet: Let's say you write a console application in native C++ for Windows. Closing the console by pressing Ctrl+C, Ctrl+Break or clicking on close window button [X] kills the process. Is there any way to handle such event and close the program gracefully? The answer is calling SetConsoleCtrlHandler() WinAPI function and implementing your own HandlerRoutine callback function. The template looks like this:
// Handler function will be called on separate thread!
static BOOL WINAPI console_ctrl_handler(DWORD dwCtrlType)
{
switch (dwCtrlType)
{
case CTRL_C_EVENT: // Ctrl+C
break;
case CTRL_BREAK_EVENT: // Ctrl+Break
break;
case CTRL_CLOSE_EVENT: // Closing the console window
break;
case CTRL_LOGOFF_EVENT: // User logs off. Passed only to services!
break;
case CTRL_SHUTDOWN_EVENT: // System is shutting down. Passed only to services!
break;
}
// Return TRUE if handled this message, further handler functions won't be called.
// Return FALSE to pass this message to further handlers until default handler calls ExitProcess().
return FALSE;
}
int main(int argc, char **argv)
{
SetConsoleCtrlHandler(console_ctrl_handler, TRUE);
...
}
If your program performs some loop and you want the user to be able to break it by closing the console or pressing Ctrl+C, you can solve it this way:
static volatile bool g_exit = false;
static BOOL WINAPI console_ctrl_handler(DWORD dwCtrlType)
{
g_exit = true;
return TRUE;
}
int main(int argc, char **argv)
{
SetConsoleCtrlHandler(console_ctrl_handler, TRUE);
initialize();
while (!g_exit)
do_a_piece_of_work();
finalize();
}