A blank fullHD display for VS Community 2015

I didn't know whether to put this request here or in beginners? But here goes.... :)

I have been playing around for months with a WinAPI sketch. I would like to open a fullHD screen (1920*1080) that is completely blank, no borders at all. I would like an invisible X (kill gadget?) in the top right hand corner (if possible). I'd like (also) to quit by ctrl/F4 or Esc (again if possible). I'd like the process to carry on running if the screen saver cuts in or if I change focus (switch to a different process?). I am working on a free version of Visual Studio 2015 :)

My sketch just opens a window, draws a Mandelbrot using setPixel and writes each pixel to a BMP file. It does a "for" loop from zoom = 1 to zoom < 50,000,000,000,000 incrementing the zoom by 5% each time.

I would be grateful if some expert could generate this skeleton for me. I have been trying off and on (unsuccessfully) for months. My process currently runs a Mandelbrot that outputs each screen to a BMP file. It "hangs" if the screen saver comes in or if/when I press ANY key or "click" the mouse. I have researched this (extensively) but can't seem to get it to work. :(

The BMP output is 1920*1080 but the screen display has borders all round :(

And, no, it is not homework - I'm a retired 71 year old BASIC programmer who is a total newbie and learned C++ on numerous Arduino microcontrolers. Moved to my desktop for speed and the fullHD screen :) I was happy with the setup/loop process on the Arduino and can't repeat the cycle on my desktop.

Currently my sketch outputs about 600 BMP files successfully but I have to constantly move the mouse and avoid pressing ANY keys till the whole process ends (when the zoom factor gets to about 50 trillion). I'd like to go above 50 trillion but that's another question ;)

I just need a working skeleton I can move my logic to, that will do as I said above. My research suggests this should be an easy request a Windows Programmer :D

Thanks in anticipation :D :D :D
Last edited on
If you just want to procedurally generate Mandelbrot images then you don't need to do anything OS related.

If you use a char array[1920][1080][3]; /* the RGB image */
you can set colors simply by doing array[x][y][0] = 0xFF; /* set red channel to 255 */

The beauty of this is that you don't interact with the OS at all and can use multiple threads to either paint this image faster or to print multiple image at once.

And you don't even need the OS to save this raw image into something that other programs can use.

You can either simply wrap the image with a TGA header if you don't need compression, by doing:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
WriteImageToFile_TGA("myimage.tga", array, 1920*1080*3, 1920, 1080);

void WriteImageToFile_TGA(const char* fileName, const LPBYTE bytes, const DWORD size, const DWORD width, const DWORD height)
{
    BYTE TGAheader[12] = {0,0,2,0,0,0,0,0,0,0,0,0};
    BYTE header[6] = { width%256,width/256,
                       height%256,height/256,
                       24,0}; //24 is for 3 color channels ; 32 for 4 color channels
    FILE* file = fopen(fileName, "wb");
    // Headers
    fwrite(TGAheader, sizeof(BYTE), 12, file);
    fwrite(header, sizeof(BYTE), 6, file);
    // Image data
    fwrite(bytes, sizeof(BYTE), size, file);
    fclose(file);
}


Or if you want compressed images, probably 50 times smaller files, then you can use lodepng to save the image as PNG:

1
2
3
4
5
6
7
void WriteImageToFile_PNG(const char* fileName, const LPBYTE bytes, const DWORD size, const DWORD width, const DWORD height)
{
    // Encode the image
    unsigned error = lodepng::encode(fileName, bytes, width, height, LCT_RGB);
    // if there's an error, display it
    if(error) printf("error %u: %s\n", error, lodepng_error_text(error));
}
Last edited on
Thanks for your response zoran404 :)

It was particularly informative, especially the compressed output option. I chose bitmap output because it is very EASY. Just the 54 byte header then the 3 char's for each pixel. I use the 3 char's to SetPixel then just write them to the BMP file - easy peasy :)

Whether I use the Windows API or not I'm still faced with handling interruptions of the screen saver and termination (early) and changing to another process leaving mine running in the background etc. Later I may want to change focus (of the Mandelbrot) with the arrow keys. All these need interaction with the OS so I still need a solution to my specific question. I'm particularly interested in opening the blank screen to paint the Mandelbrot on ;)

Still, thanks for your response :)

I would like an invisible X (kill gadget?) in the top right hand corner (if possible).


If you set the styles of the CreateWindow() or CreateWindowEx() call such that a window is created without a title bar then you'll have to test the positions as reported in the WM_LBUTTONDOWN message (WPARAM, LPARAM) so as to end the program at whatever coordinate positions you choose.

I'm a retired 71 year old BASIC programmer who is a total newbie and learned C++ on numerous Arduino microcontrolers. Moved to my desktop for speed and the fullHD screen :) I was happy with the setup/loop process on the Arduino and can't repeat the cycle on my desktop.


I'm a BASIC programmer too (or used to be). My main programming language up to a few years ago was PowerBASIC. But the genius creator of that language died 2011. It was the ultimate 32 bit programming language for Windows. But since the creator died, it'll never be 64 bit, which I mostly do now. So I moved on to C and C++ as my main languages, as I've used these languages for 20+ years too. Most of the PowerBASIC users who left moved to other versions of BASIC such as FreeBasic or PureBasic, but I believe those languages use GCC as the back end build chain.
You've obviously progressed further than me freddie1 ;)

I think I just about understand your response. I'll try it tomorrow after babysitting :)

You still don't tell me how to survive the screensaver though and how to continue running if I change (focus?) to another process (it currently "hangs") :(

Also how to create a window without a titlebar and without borders? :(

Remember you are talking to a NEWBIE here! ;)
Last edited on

Also how to create a window without a titlebar and without borders? :(


That's easy. For reference, here is about the most basic Win Api Gui window...

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
// cl Form1.cpp /O1 /Os /GS- TCLib.lib kernel32.lib user32.lib
// cl Form1.cpp /O1 /Os /GS- /link kernel32.lib user32.lib gdi32.lib
// 84,992 Bytes Standard C Linkage (LIBCMT.LIB); VC19
// 38,912 bytes Standard C Linkage (LIBCMT.LIB); VC15
//  3,584 bytes TCLib.lib Linkage
#include <windows.h>

LRESULT CALLBACK fnWndProc(HWND hwnd, unsigned int msg, WPARAM wParam, LPARAM lParam)
{
 if(msg==WM_DESTROY)
 {
    PostQuitMessage(0);
    return 0;
 }

 return (DefWindowProc(hwnd, msg, wParam, lParam));
}

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevIns, LPTSTR lpszArgument, int iShow)
{
 WNDCLASSEX wc={0};
 MSG messages;
 HWND hWnd;

 wc.lpszClassName = "Form1";
 wc.lpfnWndProc   = fnWndProc;
 wc.cbSize        = sizeof(WNDCLASSEX);
 wc.hInstance     = hInstance;
 wc.hbrBackground = (HBRUSH)COLOR_BTNSHADOW;
 RegisterClassEx(&wc);
 hWnd=CreateWindowEx(0,"Form1","Form1",WS_OVERLAPPEDWINDOW|WS_VISIBLE,200,100,325,300,HWND_DESKTOP,0,hInstance,0);
 while(GetMessage(&messages,NULL,0,0))
 {
    TranslateMessage(&messages);
    DispatchMessage(&messages);
 }

 return messages.wParam;
}


That will, however, display a window with a title bar because the 4th parameter of the CreateWindowEx() call was spercified as WS_OVERLAPPEDWINDOW | WS_VISIBLE, and those styles include bits which specify inclusion of a title bar. As an aside, the above code in PowerBASIC would be this...

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
#Compile Exe              'Disk image: 6656 bytes   Memory image: 5312 bytes.
#Include "Windows.inc"

Function fnWndProc(ByVal hWnd As Long, ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
  If wMsg = %WM_DESTROY Then
     Call PostQuitMessage(0)
     Function=0 : Exit Function
  End If

  fnWndProc=DefWindowProc(hWnd,wMsg,wParam,lParam)
End Function

Function WinMain(ByVal hInstance As Long, ByVal hPrevIns As Long, ByVal lpCmdLn As Asciiz Ptr, ByVal iShow As Long) As Long
  Local szClassName As Asciiz*16
  Local wc As WndClassEx
  Local Msg As tagMsg
  Local hWnd As Dword

  szClassName       = "Form1"
  wc.lpszClassName  = Varptr(szClassName)
  wc.lpfnWndProc    = CodePtr(fnWndProc)
  wc.cbSize         = SizeOf(wc)
  wc.hInstance      = hInstance
  wc.hbrBackground  = %COLOR_BTNSHADOW
  Call RegisterClassEx(wc)
  hWnd=CreateWindowEx(0,szClassName,szClassName,%WS_OVERLAPPEDWINDOW Or %WS_VISIBLE,200,100,325,300,0,0,hInstance,ByVal 0)
  While GetMessage(Msg,%NULL,0,0)
    Call TranslateMessage(Msg)
    Call DispatchMessage(Msg)
  Wend

  Function=msg.wParam
End Function


I'm just presenting that as you had mentioned an interest in Basic family languages, and it shows how exactly the coding corresponds with C/C++ versions of Api code. The PowerBASIC exe from the above is only 5 to 6 k in size, which beats the h*** out of VS 2015 C++ as shown above which comes in 84,992 bytes with /MT linkage.

But to answer your question about completely filling the screen and no title bar, this seems to work for me with a Windows 10 laptop running x64 OS and program compiled x64...

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
// cl Form2.cpp /O1 /Os /GS- TCLib.lib kernel32.lib user32.lib
// cl Form2.cpp /O1 /Os /GS- /link kernel32.lib user32.lib gdi32.lib
// 86,528 Bytes Standard C Linkage (LIBCMT.LIB); VC19
// 38,912 bytes Standard C Linkage (LIBCMT.LIB); VC15
//  3,584 bytes TCLib.lib Linkage
#include <windows.h>

LRESULT CALLBACK fnWndProc(HWND hwnd, unsigned int msg, WPARAM wParam, LPARAM lParam)
{
 switch(msg)
 {
   case WM_CHAR:
   {
        if(wParam==VK_ESCAPE)
        { 
           SendMessage(hwnd,WM_CLOSE,0,0);
           return 0;
        }
        break;
   }
   case WM_SYSKEYDOWN:
   {
        if((lParam&0x20000000)&&wParam==VK_DELETE)
        { 
            MessageBox(hwnd,"Alt + Delete Key!","Delete!",MB_OK);
            return 0;
        }
        break;        
   }    
   case WM_DESTROY:
   {
        PostQuitMessage(0);
        return 0;
   }
 }
 
 return (DefWindowProc(hwnd, msg, wParam, lParam));
}

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevIns, LPTSTR lpszArgument, int iShow)
{
 WNDCLASSEX wc={0};
 MSG messages;
 HWND hWnd;

 wc.lpszClassName = "Form2";
 wc.lpfnWndProc   = fnWndProc;
 wc.cbSize        = sizeof(WNDCLASSEX);
 wc.hInstance     = hInstance;
 wc.hbrBackground = (HBRUSH)COLOR_BTNSHADOW;
 wc.hCursor       = LoadCursor(NULL,IDC_ARROW);
 RegisterClassEx(&wc);
 hWnd=CreateWindowEx(0,"Form2","Form2",WS_POPUP|WS_VISIBLE,0,0,0,0,HWND_DESKTOP,0,hInstance,0);
 ShowWindow(hWnd,SW_MAXIMIZE);
 while(GetMessage(&messages,NULL,0,0))
 {
    TranslateMessage(&messages);
    DispatchMessage(&messages);
 }

 return messages.wParam;
}


Note I changed the 4th parameter of the CreateWindowEx() call to WS_POPUP|WS_VISIBLE, which is just some specific assembledge of bits. Also, to end the program - since there is no x in the title bar to close it - since there isn't any title bar, I added a WM_CHAR handler to the Window Procedure to catch VK_ESCAPE keypresses. You can end the program by hitting the [ESC] key. Otherwise you would need to close it in Task Manager.

Finally, I added a WM_SYSKEYDOWN handler to show more complex stuff such as pressing the [ALT][DEL] key combination. For [ALT] key or other such stuff you have to test bits in LPARAM with suitable AND masks.

Don't have a clue about screen saver stuff. I've never dealt with stuff like that.
Last edited on
Thanks Freddie1, exactly what I needed :)

Thanks also to Thomas1965 :)

All I need now is some free time to test this all ;)

Okay, found the time ;)

I was using "CreateWindow" not "CreateWindowEx" so I had to copy your coding piecemeal. I got a few errors, which in fixing, I then got "Failed" messages when I ran the program. Couldn't get it to compile and run correctly so I reversed editted back to my original and just applied the "WS_POPUP | WS_VISIBLE" to my original setup and it worked! A beautiful full 1920*1080 display and NO borders, no title, no taskbar, NOTHING! Absolutely PERFECT. I would never have believed such a small change could achieve so much, just what I wanted :)

I also installed your "Esc" check in WndProc but that didn't work, sorry to say. Because my actual Mandelbrot logic is in WINAPI WinMain I couldn't use the "GetMessage" blocking code so I used

1
2
3
4
if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
	TranslateMessage(&msg);   // translates this line RESULTS IN
	DispatchMessage(&msg);    // a call to WndProc(), passing the message and the HWND.
}


My program DOES action "PeekMessage" and "WndProc " but doesn't work the "Esc" path :(

I also actioned the screensaver process Thomas1965 linked me to (but not tested it yet). :)

Plus, on the good side I can now Alt/Tab and change to another process and the Mandelbrot continues running :) :) :)

It looks SO MUCH better on the full display.

I am now going to kick off a 1 to 20 trillion zoom run to test the screensaver de-activation....

Thank you both for your very helpful responses.

I will keep playing to get the "Esc" to work ;)

Edit: Just quickly.... The "Esc" just worked :)
Last edited on
The forum wouldn't let me Edit my last message again!?

Anyway, The "Esc" killed the display but the process continued running. I had to replace "SendMessage" with "DestroyWindow". The screensaver also DID activate but didn't "hang" the process like before.

Thanks to everybody for your help :)

JFYI I logged off and on again and it let me edit my previous message.... :)
Last edited on
Both CreateWindow() and CreateWindowEx() are totally usable. CreateWindowEx() has the extended styles first parameter, and also requires the WNDCLASSEX struct rather than WNDCLASS. The main difference there is WNDCLASSEX has a sizeof member, which must be filled out with the correct number for a window of the class to be instantiated.

If you are just starting with Windows programming let me give you a hint. Styles are critically important. As you saw, just changing a few bits in a number has a massive effect, and allowed you to achieve what you wanted. Windows programming using the Api is a type of C based OOP; what in OOP would be something like so...

WindowObject.TitleBar = FALSE;

...to achieve what you wanted, in C based OOP translates to setting bits or'ed into a style parameter.

All the C++ programs I posted above should build exactly as is. I tested them with Visual Studio Community 2015. However, I don't know how you are setting up your projects. I gave up on IDEs a long time ago and simply build from the command line. I've provided the command line strings I used. They all should work except those involving TCLib.lib, which is my own custom C runtime.
Thanks freddie1...

I use Visual Studio Community 2015 because it is free and legal. As said - I'm an abject newbie. I developed the Mandelbrot sketch on the Arduino IDE running an Arduino Due (83Mhz microprocessor). Each 480*320 screen could take 15 minutes to compute and draw :( The same edited sketch ran in 6 seconds on 1920*1080 on my desktop so I was "hooked". I have had no training or experience in C++ before. If something works then good.... :) If it doesn't work - I push and pull and prod (blindly) till it works. Even with lots of research I couldn't get the Blank window to work till you helped :) Believe me, I tried everything I could imagine including ~ type "styles?"....

My "Esc" routine, in fact, doesn't work! :( It destroys the window but keeps running (in the background?) and I have to kill the process with the task manager :(

I have been playing with it but, so far, no luck (and luck it is with my lack of knowledge). I used umpteen assemblers in my travels, COBOL, RPG but mainly Dartmouth BASIC so C++ is a total mystery to me. Don't get me wrong, I like it as a language but (to me) there is so much hidden. Probably caused by the disciplines of Windows etc rather than the language. I have nightmares about pointers, referencing and dereferencing etc.

My LMB click routine works (displays a requester for acknowledgement). Maybe I'll put coding into it to try to detect a "click" in the top right hand side? But then I really don't know how to stop my program.... I've tried "PostQuitMessag(0); DestroyWindow(hwnd);" but that isn't it. :( I suspect something is missing in my WndProc method?

What gets me is not knowing why something doesn't work :(

Maybe I should call a halt and do a C++ learning tutorial?

Your statement "requires the WNDCLASSEX struct rather than WNDCLASS" means nothing to me :( I got it working with "CreateWindow" so (for the moment) I'm happy. This is what I do between babysitting my 7 grandkids ;)

Thanks for your help :)



Topic archived. No new replies allowed.