So who is an expert at making a Windows GUI?

Discussion of chess software programming and technical issues.

Moderators: hgm, Rebel, chrisw

CRoberson
Posts: 2055
Joined: Mon Mar 13, 2006 2:31 am
Location: North Carolina, USA

Re: So who is an expert at making a Windows GUI?

Post by CRoberson »

My preferred way of coding a Windows GUI is Java after that HTML/Javascript.

I found Java to be fairly straight forward in its graphics coding.
jdart
Posts: 4366
Joined: Fri Mar 10, 2006 5:23 am
Location: http://www.arasanchess.org

Re: So who is an expert at making a Windows GUI?

Post by jdart »

The modern way to do Windows GUIs is with WPF. Underneath it is using DirectX. It is designed for managed code (C#).

MFC is still supported and is a good choice if you are comfortable with C++. The graphics support is somewhat primitive, though.

You can make bitmaps work but anti-aliasing and scaling can be challenging, especially with MFC/GDI. Vector graphics might be a better choice.

There are lots of 3rd-party UI toolkits such as Qt, but that looks to have a steep learning curve though, and the licensing might be a problem.

--Jon
Ed Trice
Posts: 100
Joined: Fri Sep 19, 2014 5:03 am

Re: So who is an expert at making a Windows GUI?

Post by Ed Trice »

Thanks guys.

When did Windows become such an abomination?
User avatar
Steve Maughan
Posts: 1221
Joined: Wed Mar 08, 2006 8:28 pm
Location: Florida, USA

Re: So who is an expert at making a Windows GUI?

Post by Steve Maughan »

Delphi is IMHO the best, and most productive, GUI environment for Windows. The FireMMonkey framework can also be used on Win 32, Win 64, Mac OS, iOS, Android and soon Linux.

Steve
http://www.chessprogramming.net - Maverick Chess Engine
Henk
Posts: 7216
Joined: Mon May 27, 2013 10:31 am

Re: So who is an expert at making a Windows GUI?

Post by Henk »

Skipper's GUI switched from windows to web. But I only run it locally on my computer.
Henk
Posts: 7216
Joined: Mon May 27, 2013 10:31 am

Re: So who is an expert at making a Windows GUI?

Post by Henk »

Looks like our free visual studio 2015 community does not support all new features of C# 7.0
User avatar
hgm
Posts: 27790
Joined: Fri Mar 10, 2006 10:06 am
Location: Amsterdam
Full name: H G Muller

Re: So who is an expert at making a Windows GUI?

Post by hgm »

Although I did a lot of work on WinBoard, I did not have to touch the GUI part much, as it already existed before I got involved. It uses the low-level Windows API, which is awful. (But it gives a comparaively small program, which does not have to rely on huge on-standard DLLs.)

My only advice is: try to separate the engine from the GUI. Just make the engine a console application that communicates through stdin and stdout by means of a standard protocol with the GUI. Then it can also run under other GUIs, and it becomes easier to play it against other engines. The WinBoard Alien Edition does support Checkers.

Beware that writing a GUI requires typically between 10 and 100 times more effort than writing an engine, depending on the number of features you want to support.
Stan Arts
Posts: 179
Joined: Fri Feb 14, 2014 10:53 pm
Location: the Netherlands

Re: So who is an expert at making a Windows GUI?

Post by Stan Arts »

hgm wrote: Beware that writing a GUI requires typically between 10 and 100 times more effort than writing an engine, depending on the number of features you want to support.
For something with the complexity of Winboard or Arena sure, that takes years. But Ed seems to want something fairly straight forward that you can play against. "A one-window app with the board, search info, and scrollable move list is my final aim." That should be a matter of a week with modest effort.

For Nemeton I do a bare bones Windows API setup with an OpenGL window on top to give me some sort of fast direct pixel acces and then I draw to my internal screen buffer like in the old days. It gives total freedom/creativity and can be ported to any platform but you don't get the shiny Windows buttons.
Ed Trice
Posts: 100
Joined: Fri Sep 19, 2014 5:03 am

Re: So who is an expert at making a Windows GUI?

Post by Ed Trice »

Stan Arts wrote:For Nemeton I do a bare bones Windows API setup with an OpenGL window on top to give me some sort of fast direct pixel acces and then I draw to my internal screen buffer like in the old days. It gives total freedom/creativity and can be ported to any platform but you don't get the shiny Windows buttons.
That sounds like a good solution. Do you have a screenshot of your program? I searched lazily but couldn't find anything but trees :)
Stan Arts
Posts: 179
Joined: Fri Feb 14, 2014 10:53 pm
Location: the Netherlands

Re: So who is an expert at making a Windows GUI?

Post by Stan Arts »

Ed Trice wrote: That sounds like a good solution. Do you have a screenshot of your program? I searched lazily but couldn't find anything but trees :)
Yeah,
http://talkchess.com/forum/viewtopic.ph ... 05&t=62588
though I uploaded new versions to that archive since then and there are now a bunch more options. (Coordinates next to the board, move list, some default timecontrols, black background option, uses about 80MB less RAM, better proportioned pieces etc.)

Some minimal WinAPI and OpenGL code to do this. I use (Free)Pascal but the API and OpenGL calls should be close to identical in any C variant.
Pretty sure it won't get any Windows or OpenGL expert seal of approval but it seems to work.

It creates a dynamic chunk of memory at pointer screen^ that is spixx wide and spixy high starting in the upper left corner. Starting at 0 so you can draw to spixx-1 and spixy-1.
Here a pixel is 4 bytes/32 bit but OpenGL also lets you choose different pixel types such as floating point etc.

Code: Select all

Uses Windows,GL; 
Some global variables.:

Code: Select all

Type screent=array[0..68000000] of longword;  {Ready for ultra mega wide 8K..} 

Var 

screen:^screent;
WindowClass:WndClass;
hWindow:HWnd;
wMessage:Msg;
scrnrect:Rect;
contextw:HDC;
contextgl:HGLRC;
spixx,spixy:longword; 
stopit:byte;
Here I call resize from the startup procedure as well as from the Window procedure so it's separate.

Code: Select all

procedure resize;
begin
 freemem(screen,spixx*spixy*4);
 GetClientRect(hWindow,scrnrect);
 spixx:=scrnrect.right-scrnrect.left;
 spixy:=scrnrect.bottom-scrnrect.top;
 getmem(screen,spixx*spixy*4);

 glViewport(0,0,spixx,spixy);
 glMatrixMode(GL_PROJECTION);glLoadIdentity;
 glOrtho(0,spixx-1,spixy-1,0,-1,1);
 glMatrixMode(GL_MODELVIEW);glLoadIdentity;
 glRasterPos2s(0,0);
end;
The Window procedure.

Code: Select all

function WindowProc(Window:HWnd;AMessage:UINT;WParam:WPARAM;
                    LParam:LPARAM):LRESULT;stdcall;export;
begin
 if AMessage=wm_Destroy then begin PostQuitMessage(0);stopit:=1;end;
 if (AMessage=wm_Sizing)or(AMessage=wm_Size)or(AMessage=wm_Move) then
  resize;
 WindowProc:=DefWindowProc(Window,AMessage,WParam,LParam);
end;
And message pump.

Code: Select all

procedure windowsmessagepump;
begin
 while PeekMessage(@wMessage,0,0,0,PM_REMOVE) do begin
  TranslateMessage(wMessage);DispatchMessage(wMessage);end;
end;
Start. Create a 1024 by 768 window and the OpenGL thing ontop. At the end before doing anything it calls resize then it's ready for action.

Code: Select all

procedure startup;
var PixelFormat:GLuint;
  h_Instance:HINST;
  pfd:TPIXELFORMATDESCRIPTOR;
begin
 stopit:=0;spixx:=1024;spixy:=768;
 getmem(screen,spixx*spixy*4);
 WindowClass.Style:=cs_hRedraw or cs_vRedraw;
 WindowClass.lpfnWndProc:=WndProc(@WindowProc);
 WindowClass.cbClsExtra:=0;
 WindowClass.cbWndExtra:=0;
 WindowClass.hInstance:=system.MainInstance;
 WindowClass.hIcon:=LoadIcon(0,idi_application);
 WindowClass.hCursor:=LoadCursor(0,idc_arrow);
 WindowClass.hbrBackground:=GetStockObject(BLACK_BRUSH);
 WindowClass.lpszMenuName:=nil;
 WindowClass.lpszClassName:='Test';
 if RegisterClass(WindowClass)=0 then exit;
 hWindow:=CreateWindow('Test','Test',ws_OverlappedWindow,cw_UseDefault,
  cw_UseDefault,spixx,spixy,0,0,system.MainInstance,nil);
 if hWindow<>0 then begin
  ShowWindow&#40;hWindow,CmdShow&#41;;ShowWindow&#40;hWindow,SW_SHOW&#41;;
  UpdateWindow&#40;hWindow&#41;;end else exit;
 contextw&#58;=GetDC&#40;hWindow&#41;;

 pfd.nSize&#58;=SizeOf&#40;TPIXELFORMATDESCRIPTOR&#41;;pfd.nVersion&#58;=1;
 pfd.dwFlags&#58;=PFD_DRAW_TO_WINDOW or PFD_SUPPORT_OPENGL;
 pfd.iPixelType&#58;=PFD_TYPE_RGBA;
 pfd.cColorBits&#58;=32;pfd.cRedBits&#58;=0;
 pfd.cRedShift&#58;=0;pfd.cGreenBits&#58;=0;
 pfd.cGreenShift&#58;=0;pfd.cBlueBits&#58;=0;
 pfd.cBlueShift&#58;=0;pfd.cAlphaBits&#58;=0;
 pfd.cAlphaShift&#58;=0;pfd.cAccumBits&#58;=0;
 pfd.cAccumRedBits&#58;=0;pfd.cAccumGreenBits&#58;=0;
 pfd.cAccumBlueBits&#58;=0;pfd.cAccumAlphaBits&#58;=0;
 pfd.cDepthBits&#58;=16;pfd.cStencilBits&#58;=0;
 pfd.cAuxBuffers&#58;=0;pfd.iLayerType&#58;=PFD_MAIN_PLANE;
 pfd.bReserved&#58;=0;pfd.dwLayerMask&#58;=0;
 pfd.dwVisibleMask&#58;=0;pfd.dwDamageMask&#58;=0;
 PixelFormat&#58;=ChoosePixelFormat&#40;contextw,@pfd&#41;;
 SetPixelFormat&#40;contextw,PixelFormat,@pfd&#41;;
 contextgl&#58;=wglCreateContext&#40;contextw&#41;;
 wglMakeCurrent&#40;contextw,contextgl&#41;;
 glClearColor&#40;0,0,0,1&#41;;glShadeModel&#40;GL_FLAT&#41;;
 glDepthFunc&#40;GL_ALWAYS&#41;;glDisable&#40;GL_DEPTH_TEST&#41;;
 glPointSize&#40;1&#41;;glLineWidth&#40;1&#41;;glpixelzoom&#40;1,-1&#41;;
 glClear&#40;GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT&#41;;glLoadIdentity;
 resize;
end;

procedure stoppen;
begin 
 freemem&#40;screen,spixx*spixy*4&#41;;
 wglMakeCurrent&#40;contextw,0&#41;;wglDeleteContext&#40;contextgl&#41;;
 ReleaseDC&#40;hWindow,contextw&#41;;DestroyWindow&#40;hWindow&#41;;
end;
Draw the screen buffer to screen and clear it in this case with black. (0)

Code: Select all

procedure drawscrn;
begin
 gldrawpixels&#40;spixx,spixy,GL_RGBA,GL_UNSIGNED_BYTE,@screen^);
 glflush;
 filldword&#40;screen^,spixx*spixy,0&#41;;
end;
And a main part.

Code: Select all

begin
startup; 

repeat

&#123;do and draw something..&#125; 

drawscrn;

Windowsmessagepump;

until stopit=1;

stoppen; 
end.