NO

Author Topic: Best GUI lib to use with Pelles?  (Read 21838 times)

MichaelW

  • Guest
Re: Best GUI lib to use with Pelles?
« Reply #30 on: May 23, 2015, 07:40:51 AM »
I don't really understand the discussion here, but with the right support code, in-memory dialogs are easy to code and use. Note that none of the following code has been thoroughly tested, and that I had to remove a lot of the commenting to keep the size below the post limit.
imdialog.c:
Code: [Select]
#include <stdlib.h>
#include <stdio.h>
#include <windows.h>
#include <richedit.h>
#include <commctrl.h>

//---------------------------------------------------------------------
// This module provides a quick and easy method of creating a dialog
// box template in allocated memory and creating a modal or modeless
// dialog from the template.
//
// The dialog box template consists of a single DLGTEMPLATE structure
// followed by three or four variable-length arrays, followed by zero
// or more DLGITEMTEMPLATE structures each followed by three variable-
// length arrays. The DLGTEMPLATE structure and the associated arrays
// define the dialog window, and the DLGITEMTEMPLATE structures and
// the associated arrays define the controls in the dialog.
//
// The variable-length arrays consist of WORD (16-bit) elements.
//
// The first three arrays following the DLGTEMPLATE structure specify
// the menu, class, and title for the dialog. The three arrays
// following each DLGITEMTEMPLATE structure specify the class, title,
// and creation data for the control. Each of these arrays will have
// at least one element, and the system will interpret the contents
// of the array based on the value of the first element. For the
// dialog menu, class, and title arrays, and the control creation
// data array, if the first element is zero then the array is
// effectively empty and there are no other elements. For the dialog
// menu and class arrays, and the control class and title arrays, if
// the first element is FFFFh then the second element contains the
// ordinal value of a resource or a predefined class, and the array
// contains no other elements. For the dialog menu, class, and title
// arrays, and the control class and title arrays, if the first
// element is any value other than zero or FFFFh then the array is
// assumed to be a null-terminated Unicode string. Depending on the
// array, this Unicode string can specify the name of a menu resource,
// a registered class, the dialog title, or the initial text for a
// control. For the control creation data array, if the first element
// is non-zero then it contains the length, in bytes, of the creation
// data that follows. The fourth array following the DLGTEMPLATE
// structure, which the system expects to be present when the dialog
// style includes DS_SETFONT, specifies the font point size value in
// the first element, followed by the name of the typeface as a null-
// terminated Unicode string.
//
// This implementation does not permit a menu or class specification
// for the dialog, or creation data for the controls.
//
// The DLGTEMPLATE and DLGITEMTEMPLATE structures must be aligned
// on a DWORD (32-bit) boundary. The variable-length arrays that
// follow the structures must start on a WORD boundary, but with
// WORD-size elements and the structure sizes and alignment
// requirements, this should be automatic.
//---------------------------------------------------------------------

#ifndef TEMPLATE_BUFFER_KB
#define TEMPLATE_BUFFER_KB 20
#endif

LPDLGTEMPLATE g_lpdt;
LPWORD g_lpw;

void GenUString( LPCSTR lpAnsiString )
{
    int lenWstr;

    if(lpAnsiString)
    {

        lenWstr = MultiByteToWideChar( CP_ACP,
                                       MB_PRECOMPOSED,
                                       lpAnsiString,
                                       -1,
                                       (LPWSTR)g_lpw,
                                       0 );

        g_lpw += MultiByteToWideChar( CP_ACP,
                                      MB_PRECOMPOSED,
                                      lpAnsiString,
                                      -1,
                                      (LPWSTR)g_lpw,
                                      lenWstr );
    }
    else
    {
        g_lpw += 1;
    }
}

INT_PTR CreateModalDialog( HWND hwndParent,
                           DLGPROC lpDialogProc,
                           LPARAM dwInitParam )
{
    INT_PTR nResult;

    GlobalReAlloc( (HGLOBAL)g_lpdt,(int)g_lpw - (int) g_lpdt + 1,0 );
    nResult = DialogBoxIndirectParam( GetModuleHandle(NULL),
                                      g_lpdt,
                                      hwndParent,
                                      lpDialogProc,
                                      dwInitParam );
    GlobalFree( g_lpdt );
    return nResult;
}


HWND CreateModelessDialog( HWND hwndParent,
                           DLGPROC lpDialogProc,
                           LPARAM dwInitParam )
{
    HWND h;

    GlobalReAlloc( (HGLOBAL) g_lpdt,(int)g_lpw - (int)g_lpdt + 1, 0 );

    h = CreateDialogIndirectParam( GetModuleHandle(NULL),
                                   g_lpdt,
                                   hwndParent,
                                   lpDialogProc,
                                   dwInitParam );
    GlobalFree( g_lpdt );

    return h;
}

void Dialog( LPCSTR lpTitle,
             DWORD style,
             short x,
             short y,
             short cx,
             short cy,             
             short pointSize,
             LPCSTR lpTypeFace,
             short controlCount )   
{
    g_lpdt = GlobalAlloc( GMEM_FIXED | GMEM_ZEROINIT,
                          1024 * TEMPLATE_BUFFER_KB );
 
    g_lpdt->style = style;
    g_lpdt->cdit = controlCount;
    g_lpdt->x  = x;
    g_lpdt->y  = y;
    g_lpdt->cx = cx;
    g_lpdt->cy = cy;
 
 
    g_lpw = (LPWORD) (g_lpdt + 1);

   
    g_lpw += 1;
    g_lpw += 1;

    GenUString(lpTitle);
 
       
    if( pointSize && lpTypeFace )
    {
        g_lpdt->style |= DS_SETFONT;
        *g_lpw = pointSize;
        g_lpw += 1;
        GenUString( lpTypeFace );
    }
}

void Control( LPCSTR lpClass,
              LPCSTR lpTitle,
              DWORD style,
              short x,
              short y,
              short cx,
              short cy,
              short resourceID,
              WORD controlID )
{
    LPDLGITEMTEMPLATE lpdit;
    unsigned int ui;

    ui = (ULONG)g_lpw;
    ui += 3;
    ui &= -4;
    g_lpw = (LPWORD)ui;

    lpdit = (LPDLGITEMTEMPLATE) g_lpw;

    lpdit->style = WS_CHILD | WS_VISIBLE | style;
    lpdit->x = x;
    lpdit->y = y;
    lpdit->cx = cx;
    lpdit->cy = cy;
    lpdit->id = controlID;

    g_lpw = (LPWORD)(lpdit + 1);

    GenUString( lpClass );

    if(resourceID)
    {
        *g_lpw = 0xffff;
        g_lpw += 1;
        *g_lpw = resourceID;
        g_lpw += 1;
    }
    else
    {
        GenUString( lpTitle );
    }
   
    g_lpw += 1;
}

void PushButton( LPCSTR lpCaption,
                 DWORD style,
                 short x,
                 short y,
                 short cx,
                 short cy,
                 WORD controlID )
{
    Control( "BUTTON",
             lpCaption,
             BS_PUSHBUTTON | style,
             x,
             y,
             cx,
             cy,
             0,
             controlID );
}

void DefPushButton( LPCSTR lpCaption,
                    DWORD style,
                    short x,
                    short y,
                    short cx,
                    short cy,
                    WORD controlID )
{
    Control( "BUTTON",
             lpCaption,
             BS_DEFPUSHBUTTON | style,
             x,
             y,
             cx,
             cy,
             0,
             controlID );
}

void AutoCheckBox( LPCSTR lpCaption,
                   DWORD style,
                   short x,
                   short y,
                   short cx,
                   short cy,
                   WORD controlID )
{
    Control( "BUTTON",
             lpCaption,
             BS_AUTOCHECKBOX | style,
             x,
             y,
             cx,
             cy,
             0,
             controlID );
}

void AutoRadioButton( LPCSTR lpCaption,
                      DWORD style,
                      short x,
                      short y,
                      short cx,
                      short cy,
                      WORD controlID )
{
    Control( "BUTTON",
             lpCaption,
             BS_AUTORADIOBUTTON | style,
             x,
             y,
             cx,
             cy,
             0,
             controlID );
}

void GroupBox( LPCSTR lpCaption,
               DWORD style,
               short x,
               short y,
               short cx,
               short cy,
               WORD controlID )
{
    Control( "BUTTON",
             lpCaption,
             BS_GROUPBOX  | style,
             x,
             y,
             cx,
             cy,
             0,
             controlID );
}

void EditText( LPCSTR lpText,
               DWORD style,
               short x,
               short y,
               short cx,
               short cy,
               WORD controlID )
{
    Control( "EDIT",
             lpText,
             style,
             x,
             y,
             cx,
             cy,
             0,
             controlID );
}

void LText( LPCSTR lpText,
            DWORD style,
            short x,
            short y,
            short cx,
            short cy,
            WORD controlID )
{
    Control( "STATIC",
             lpText,
             SS_LEFT | style,
             x,
             y,
             cx,
             cy,
             0,
             controlID );
}

void RText( LPCSTR lpText,
            DWORD style,
            short x,
            short y,
            short cx,
            short cy,
            WORD controlID )
{
    Control( "STATIC",
             lpText,
             SS_RIGHT | style,
             x,
             y,
             cx,
             cy,
             0,
             controlID );
}

void CText( LPCSTR lpText,
            DWORD style,
            short x,
            short y,
            short cx,
            short cy,
            WORD controlID )
{
    Control( "STATIC",
             lpText,
             SS_CENTER | style,
             x,
             y,
             cx,
             cy,
             0,
             controlID );
}

void ListBox( LPCSTR junk,
              DWORD style,
              short x,
              short y,
              short cx,
              short cy,
              WORD controlID)
{
    Control( "LISTBOX",
             0,
             style,
             x,
             y,
             cx,
             cy,
             0,
             controlID );
}

void ComboBox( LPCSTR junk,
               DWORD style,
               short x,
               short y,
               short cx,
               short cy,
               WORD controlID )
{
    Control( "COMBOBOX",
             0,
             style,
             x,
             y,
             cx,
             cy,
             0,
             controlID );
}

void ScrollBar( LPCSTR junk,
                DWORD style,
                short x,
                short y,
                short cx,
                short cy,
                WORD controlID )
{
    Control( "SCROLLBAR",
             0,
             style,
             x,
             y,
             cx,
             cy,
             0,
             controlID );
}

//--------------------------------------------------------------
// This for Rich Edit version 2/3, LoadLibrary("RICHED20.DLL");
//--------------------------------------------------------------

void RichEdit( LPCSTR junk,
               DWORD style,
               short x,
               short y,
               short cx,
               short cy,
               WORD controlID )
{
    Control( RICHEDIT_CLASS,
             0,
             style,
             x,
             y,
             cx,
             cy,
             0,
             controlID );
}

void InitCommonCtrls( void )
{
    INITCOMMONCONTROLSEX iccex = {sizeof(INITCOMMONCONTROLSEX),
                                 ICC_ANIMATE_CLASS      | \
                                 ICC_BAR_CLASSES        | \
                                 ICC_COOL_CLASSES       | \
                                 ICC_DATE_CLASSES       | \
                                 ICC_HOTKEY_CLASS       | \
                                 ICC_INTERNET_CLASSES   | \
                                 ICC_LISTVIEW_CLASSES   | \
                                 ICC_PAGESCROLLER_CLASS | \
                                 ICC_PROGRESS_CLASS     | \
                                 ICC_TAB_CLASSES        | \
                                 ICC_TREEVIEW_CLASSES   | \
                                 ICC_UPDOWN_CLASS       | \
                                 ICC_USEREX_CLASSES     | \
                                 ICC_WIN95_CLASSES };
    InitCommonControlsEx( &iccex );
}
imdialog.h:
Code: [Select]
void GenUString( LPCSTR lpAnsiString );

INT_PTR CreateModalDialog( HWND hwndParent,
                           DLGPROC lpDialogProc,
                           LPARAM dwInitParam );

HWND CreateModelessDialog( HWND hwndParent,
                           DLGPROC lpDialogProc,
                           LPARAM dwInitParam );

void Dialog( LPCSTR lpTitle,
             DWORD style,
             short x,
             short y,
             short cx,
             short cy,
             short pointSize,
             LPCSTR lpTypeFace,
             short controlCount );

void Control( LPCSTR lpClass,
              LPCSTR lpTitle,
              DWORD style,
              short x,
              short y,
              short cx,
              short cy,
              short resourceID,
              WORD controlID );

void PushButton( LPCSTR lpCaption,
                 DWORD style,
                 short x,
                 short y,
                 short cx,
                 short cy,
                 WORD controlID );

void DefPushButton( LPCSTR lpCaption,
                    DWORD style,
                    short x,
                    short y,
                    short cx,
                    short cy,
                    WORD controlID );

void AutoCheckBox( LPCSTR lpCaption,
                   DWORD style,
                   short x,
                   short y,
                   short cx,
                   short cy,
                   WORD controlID );

void AutoRadioButton( LPCSTR lpCaption,
                      DWORD style,
                      short x,
                      short y,
                      short cx,
                      short cy,
                      WORD controlID );

void GroupBox( LPCSTR lpCaption,
               DWORD style,
               short x,
               short y,
               short cx,
               short cy,
               WORD controlID );

void EditText( LPCSTR lpText,
               DWORD style,
               short x,
               short y,
               short cx,
               short cy,
               WORD controlID );

void LText( LPCSTR lpText,
            DWORD style,
            short x,
            short y,
            short cx,
            short cy,
            WORD controlID );

void RText( LPCSTR lpText,
            DWORD style,
            short x,
            short y,
            short cx,
            short cy,
            WORD controlID );

void CText( LPCSTR lpText,
            DWORD style,
            short x,
            short y,
            short cx,
            short cy,
            WORD controlID );

void ListBox( LPCSTR junk,
              DWORD style,
              short x,
              short y,
              short cx,
              short cy,
              WORD controlID);

void ComboBox( LPCSTR junk,
               DWORD style,
               short x,
               short y,
               short cx,
               short cy,
               WORD controlID );

void ScrollBar( LPCSTR junk,
                DWORD style,
                short x,
                short y,
                short cx,
                short cy,
                WORD controlID );

void RichEdit( LPCSTR junk,
               DWORD style,
               short x,
               short y,
               short cx,
               short cy,
               WORD controlID );

void InitCommonCtrls( void );
simple.c:
Code: [Select]
#include <windows.h>
#include <richedit.h>
#include <commctrl.h>
#include "imdialog.h"

INT_PTR CALLBACK DialogProc( HWND hwndDlg,
                             UINT uMsg,
                             WPARAM wParam,
                             LPARAM lParam )
{
  switch ( uMsg )
  {
    case WM_INITDIALOG :
      return 1;
    case WM_COMMAND :
      if ( wParam == IDCANCEL || wParam == 101 )
          EndDialog( hwndDlg, 0 );
      break;
    case WM_CLOSE :
            EndDialog( hwndDlg, 0 );
  }
  return 0;
}

int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nShowCmd)

    Dialog("Test",WS_OVERLAPPED|WS_SYSMENU|DS_CENTER,0,0,100,80,10,"comic sans ms",2);
    EditText("",WS_BORDER|WS_TABSTOP,10,10,77,10,100);
    PushButton("OK",WS_TABSTOP,29,40,40,10,101);
    CreateModalDialog(0,DialogProc,0);
    exit(0);
}



migf1

  • Guest
Re: Best GUI lib to use with Pelles?
« Reply #31 on: May 31, 2015, 11:10:55 AM »
For me, and as far as GUI programming is concerned, the most obvious inconvenience is that C does not directly support OOP (GUI and OOP go hand by hand for decades). That's also IMO the main problem with Win32 API. However, frameworks like GTK+ are implemented in a fully OO mindset, thus overcoming most of the potential inconveniences when the GUI gets too complicated.

GTK+ and its dependencies are kind of a "beast", but they provide everything (or almost everything) you expect from a modern GUI framework (for example, it even lets you style your widgets using css if you choose so). Its learning curve is not harder than Win32 API's and (always IMO) it's a much more fun and productive framework. Glade can also prove quite handy as a RAD tool for the initial design of the GUI.


henrin

  • Guest
Re: Best GUI lib to use with Pelles?
« Reply #32 on: September 05, 2015, 04:32:18 PM »
Many questions for a simple GUI projects in C.
Win32 is almost perfect, but...

I tried to fill the gap for casual programmers
with SGL - a simple layer on top on Win32 as I told
on may 21th.

Now it is released, see here :
http://forum.pellesc.de/index.php?topic=6788.0

As told by mifg1, "GUI and OOP go hand by hand for decades".
That is why SGL is somewhat OOP, ie. :
- a widget can be duplicated,
- callback functions are defined per object (not per Window class).

And more: SGL does not interfere with your data.