News:

Download Pelles C here: http://www.pellesc.se

Main Menu

New Year, new URL

Started by Pelle, January 10, 2026, 09:18:21 PM

Previous topic - Next topic

Robert

Quote from: Pelle on January 11, 2026, 11:02:49 PM
Quote from: alderman2 on January 11, 2026, 09:51:45 PMI don't think they're the ones you should lean on, but rather those who still program the basic language C.
Sure. The question is what this means in practice.

C on Windows in 2026+ will mainly be hobbyists (certainly for this project), where the latest and greatest isn't that important.
At my first real programming job in ~1985 I could have gone the Unix route (probably), but it wasn't much of an option back then... and 40+ years later it's still not an option...
After Windows and Unix there are roughly zero desktop operating-systems to choose from...

Microsoft have managed to mess up Windows quite a bit in recent years, focusing on irrelevant things (for enough people to matter), so it's not an obvious choice - except there are few other options. Now that I'm almost finished with ARM64 (still a potential flop), it's not clear what I should do. Write more examples? Not that exiting to be honest...

I'm not an innovator, and right now I can't find much inspiration anywhere...

Hi Pelle:

Thank you for your continuing amazing work !

Bored ? Nothing to do ? SWAR and AVX512 may offer some entertainment.

Check out Wojciech Muła's work. A good place to start is

http://0x80.pl/notesen/2016-09-17-avx512-foundation-base64.html

Lots of code at GitHub at

https://github.com/WojciechMula

Collection of Toys at

https://github.com/WojciechMula/toys

Thanks again for providing all of us tinkers with your tool for toys.

bitcoin

Hello, Pelle
How about creating some kind of library to simplify GUI application development? It's no secret that things are pretty bad in this area on Windows right now. C++ Builder was ideal, but it either died or became too complex. Qt is a heavy monster, and it's for C++ anyway. There's really nothing else. What if we made something like that for C?

TimoVJL

#17
Multitarget project file would be nice feature  ;)

EDIT: 2026-02-04
A project file, that support Release and debug output folders could be useful.
User could have both version for testing.
Now have to create another project file for independent debug version and have to have a workspace for them to keep them together.
May the source be with you

Pelle

Quote from: alderman2 on January 12, 2026, 06:05:10 PMWhy not create a new programming language?
No, I think for me "Pelles C" will just be "C".

Quote from: Robert on January 13, 2026, 09:11:31 PMBored ? Nothing to do ? SWAR and AVX512 may offer some entertainment.
Well, I added AVX-512F... a lot of work, but not much interest. Intel seemed to care most. Not sure where they will be in a few years.
Adding AVX-512<letter soup> is just more work. Nothing really new to learn.

Quote from: Robert on January 13, 2026, 09:11:31 PMCheck out Wojciech Muła's work.
I will do that.

Quote from: bitcoin on January 14, 2026, 05:28:04 PMHow about creating some kind of library to simplify GUI application development? It's no secret that things are pretty bad in this area on Windows right now. C++ Builder was ideal, but it either died or became too complex. Qt is a heavy monster, and it's for C++ anyway. There's really nothing else. What if we made something like that for C?
Well... it was one idea ~20 years ago, but it didn't happen then.
A quick solution would be a very basic library with narrow focus. Unless you happen to fit into this narrow focus it won't be of much help. A better solution would take more work, starting with a well researched specification. By the time this is done, perhaps the world has moved on...?

Quote from: TimoVJL on January 14, 2026, 09:33:45 PMMultitarget project file would be nice feature  ;)
I very much prefer to have one target per project. I think the concept of workspaces is good enough. Maybe not perfect, but good enough...
/Pelle

alderman2

I have created a library for Windows-specific functions etc. I have about 800 such functions. This is what it looks like to open a window and place it in the center:

hwnd=ac_WindowCreate_1(hInst,"Xxxx",100,100,1200,720,"MIN_MAX_CLO"); //
ac_WindowSetCenterPos_1(hwnd);


A push buttons:
hwnd_G_Knapp_1   =ac_ButtonSimpleCreate_1(hwnd,   0,0,120,30,"Name 1","C","SHADOW",BUTT-1);
hwnd_G_Knapp_2   =ac_ButtonSimpleCreate_1(hwnd, 120,0,120,30,"Name 2","C","SHADOW",BUTT-2);
hwnd_G_Knapp_3   =ac_ButtonSimpleCreate_1(hwnd, 240,0,120,30,"Name 3","C","SHADOW",BUTT-3);
hwnd_G_Knapp_4   =ac_ButtonSimpleCreate_1(hwnd, 360,0,120,30,"Name 4","C","SHADOW",BUTT-4);
hwnd_G_Knapp_5   =ac_ButtonSimpleCreate_1(hwnd, 480,0,120,30,"Name 5","C","SHADOW",BUTT-5);
hwnd_G_Knapp_6   =ac_ButtonSimpleCreate_1(hwnd, 600,0,120,30,"Name 6","C","SHADOW",BUTT-6);
hwnd_G_Knapp_7   =ac_ButtonSimpleCreate_1(hwnd, 720,0,120,30,"Name 7","C","SHADOW",BUTT-7);
hwnd_G_Knapp_8   =ac_ButtonSimpleCreate_1(hwnd, 840,0,120,30,"Name 9","C","SHADOW",BUTT-8);

This is made by me for me. If someone else had created my library, I would probably still have built this because it suits me. That's why you should probably make libraries like this yourself, you get the most benefit from it that way.

TimoVJL

#20
A poide resource editor can be useful for designing GUI.
Just read res-file for dynamic controls to window.
As far I remember, there is couple examples of it.


Dialog code from res-file

ResDlgConv3.c
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <stdio.h>

int ProcessFile(PBYTE pMem, int nMax);

int main(int argc, char **argv)
{
    HANDLE hFile, hMapping;
    VOID *pMem;

    if (argc < 2) {
        printf("Usage: ResDlgDump.exe <file>\n");
        return 1;
    }
    hFile = CreateFile(argv[1], GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
    if (hFile != INVALID_HANDLE_VALUE)
    {
        hMapping = CreateFileMapping(hFile, NULL, PAGE_READONLY, 0, 0, NULL);
        if (hMapping)
        {
            pMem = MapViewOfFile(hMapping, FILE_MAP_READ, 0, 0, 0);
            if (pMem)
            {
                DWORD dwSize = GetFileSize(hFile, NULL);
                ProcessFile(pMem, dwSize);
                UnmapViewOfFile(pMem);
            } else
                printf("File open error");
            CloseHandle(hMapping);
        } else
            printf("FileMapping error");
        CloseHandle(hFile);
    }
    else
        printf("File open error");
    return 0;
}

typedef struct tagRESOURCEHEADER {
    DWORD DataSize;
    DWORD HeaderSize;
    DWORD Type;    // variable size
    DWORD Name;    // variable size
    DWORD DataVersion;
    WORD MemoryFlags;
    WORD LanguageId;
    DWORD Version;
    DWORD Characteristics;
}RESOURCEHEADER, *PRESOURCEHEADER;

void DumpDialog(PBYTE pByte, PBYTE pMem);

int ProcessFile(PBYTE pMem, int nMax)
{
    PBYTE pByte = pMem;
    do {
        if (((PRESOURCEHEADER)pByte)->Type == 0x5FFFF) {    // Dialog
            DumpDialog(pByte, pMem);
        }
        DWORD nSize = ((PRESOURCEHEADER)pByte)->DataSize + ((PRESOURCEHEADER)pByte)->HeaderSize;
        pByte += (nSize + 3) & ~3;
    } while (pByte < pMem + nMax);
    return 0;
}
//#pragma pack(push, 2)
typedef struct {
    WORD dlgVer;
    WORD signature;
    DWORD helpID;
    DWORD exStyle;
    DWORD style;
    WORD cDlgItems;
    short x;
    short y;
    short cx;
    short cy;
/*    sz_Or_Ord menu;
    sz_Or_Ord windowClass;
    WCHAR title[titleLen];
    short pointsize;
    short weight;
    short bItalic;
    WCHAR font[fontLen]; */
} DLGTEMPLATEEX, *LPDLGTEMPLATEEX;
// https://docs.microsoft.com/en-us/windows/desktop/dlgbox/dlgitemtemplateex
//https://blogs.msdn.microsoft.com/oldnewthing/20040623-00/?p=38753
typedef struct {
    DWORD helpID;
    DWORD dwExtendedStyle;
    DWORD style;
    WORD x;
    WORD y;
    WORD cx;
    WORD cy;
    DWORD id;
/*    sz_Or_Ord windowClass;
    sz_Or_Ord title;
    WORD extraCount; */
} DLGITEMTEMPLATEEX, *LPDLGITEMTEMPLATEEX;
//#pragma pack(pop)
WCHAR *GetCtlClassW(WORD wClass)
{
    switch (wClass) {
        case 0x0080: return L"BUTTON"; break;
        case 0x0081: return L"EDIT"; break;
        case 0x0082: return L"STATIC"; break;
        case 0x0083: return L"LISTBOX"; break;
        case 0x0084: return L"SCROLLBAR"; break;
        case 0x0085: return L"COMBOBOX"; break;
    }
    return NULL;
}

void AddDlgRCCodeEx(PRESOURCEHEADER pResHdr, LPDLGTEMPLATEEX pDlgEx,PWORD pMenu, PWORD pCaption, PBYTE pPar);
void AddCtlRCCodeEx(LPDLGITEMTEMPLATEEX pDlgItem, PWORD pClass, PWORD pTitle);
void AddDlgCodeEx(LPDLGTEMPLATEEX pDlgEx, PWORD pMenu, PWORD pCaption);
void AddCtlCodeEx(LPDLGITEMTEMPLATEEX pDlgItem, PWORD pClass, PWORD pTitle);


void DumpDialog(PBYTE pByte, PBYTE pMem)
{
    PRESOURCEHEADER pResHdr = (PRESOURCEHEADER)pByte;
    PWORD pPtr = (PWORD)(pByte + ((PRESOURCEHEADER)pByte)->HeaderSize);
    DWORD nSize = *(DWORD*)pByte;
    DWORD nItems;
    if (*(DWORD*)pPtr != 0xFFFF0001) {    // Standard Dialog
        DLGTEMPLATE *pDlg = (DLGTEMPLATE*)(pByte + ((PRESOURCEHEADER)pByte)->HeaderSize);
        nItems = pDlg->cdit;
        //printf("style: %Xh\n", pDlg->style);
        if (pDlg->style & DS_SETFONT)
            pPtr += sizeof(DWORD);
        for (unsigned i=0; i<nItems; i++) {
            pPtr = (PWORD)((DWORD_PTR)(pPtr + 3) & ~3);
            LPDLGITEMTEMPLATE pDlgItem = (LPDLGITEMTEMPLATE)pPtr;
            //printf("\nOfs: %Xh\n", pPtr - pMem);
        }
    } else {    // Extended Dialog
        //DLGTEMPLATEEX1 *pDlgEx = (DLGTEMPLATEEX1*)(pByte + ((PRESOURCEHEADER)pByte)->HeaderSize);
        DLGTEMPLATEEX *pDlgEx = (DLGTEMPLATEEX*)pPtr;
        nItems = pDlgEx->cDlgItems;
        pPtr = (PWORD)((PBYTE)pPtr + sizeof(DLGTEMPLATEEX));
        pPtr = (PWORD)((DWORD_PTR)((PBYTE)pPtr + 3) & ~3);    // if struct packed 1
        PWORD pMenu = pPtr;
        if (*(WORD*)pPtr) {    // Menu ?
            while (pPtr) pPtr++;
            pPtr ++;    // past zero
        } else {
            pPtr ++;
        }
        //printf("\nCaption: %Xh\n", (PBYTE)pPtr - pMem);
        PWORD pCaption = pPtr;
        if (*(WORD*)pPtr) {    // Caption ?
            while (*pPtr) pPtr++;
            pPtr ++;    // past zero
        } else {
            pPtr ++;
        }
        //printf("\nOfs: %Xh\n", pPtr - pMem);
        PBYTE pPar =(PBYTE) pPtr;
        // Font name
        pPtr += 3;
        while (*pPtr) pPtr++;
            pPtr ++;    // past zero
        //if (pDlgEx->style & DS_SETFONT)
        //    pPtr ++;
        AddDlgRCCodeEx(pResHdr, pDlgEx, pMenu, pCaption, pPar);
        AddDlgCodeEx(pDlgEx, pMenu, pCaption);
        printf("{\n");
        for (unsigned i=0; i<nItems; i++) {
            pPtr = (PWORD)((DWORD_PTR)((PBYTE)pPtr + 3) & ~3);
            //printf("%Xh", (PBYTE)pPtr - pMem);
            LPDLGITEMTEMPLATEEX pDlgItem = (LPDLGITEMTEMPLATEEX)pPtr;
            PWORD pClass, pTitle;
            //printf("\nOfs: %Xh\n", pPtr - pMem);
            //pPtr += sizeof(DLGITEMTEMPLATEEX);
            pPtr = (PWORD)((PBYTE)pPtr + sizeof(DLGITEMTEMPLATEEX));
            //printf("\npClass: %Xh\n", pPtr - pMem);
            pClass = (PWORD)pPtr;
            if (*(WORD*)pPtr) {    // Class name or id ?
                if (*pClass == 0xFFFF) {
                    pPtr += 2;    // FFFFh and id
                } else {
                    while (*(WORD*)pPtr) pPtr++;
                    pPtr ++;    // past zero
                }
            } else {
                pPtr ++;
            }
            pTitle = (PWORD)pPtr;
            if (*(WORD*)pPtr) {    // Title name or id ?
                if (*pTitle == 0xFFFF)
                    pPtr += 2;
                else {
                    while (*(WORD*)pPtr) pPtr++;
                    pPtr ++;    // past zero
                }
            } else {
                pPtr ++;
            }
            if (*(WORD*)pPtr) {    // CreationData
                pPtr += *pPtr;
            } else pPtr ++;
            AddCtlRCCodeEx(pDlgItem, pClass, pTitle);
            AddCtlCodeEx(pDlgItem, pClass, pTitle);
            //printf("\n");
        }
        printf("}\n");
    }
}

void AddDlgRCCodeEx(PRESOURCEHEADER pResHdr, LPDLGTEMPLATEEX pDlgEx, PWORD pMenu, PWORD pCaption, PBYTE pPar)
{
    if ((WORD)pResHdr->Name == 0xFFFF)    // numeric id
        printf("%d ", HIWORD(pResHdr->Name));
    else
        printf("Name: %ls\n", (WCHAR*)pResHdr->Name);
    printf("DIALOGEX %d,%d,%d,%d\n", pDlgEx->x, pDlgEx->y, pDlgEx->cx, pDlgEx->cy);
    printf("STYLE 0x%X\n", pDlgEx->style);
    printf("CAPTION \"%ls\"\n", pCaption);
    if (*pMenu) printf("MENU \"%ls\"\n", pMenu);
    printf("FONT %d \"%ls\"", *(WORD*)pPar, (WCHAR*)pPar+6);
    printf(",%d,%d,%d\n", *(pPar+3), *(pPar+4), *(pPar+5));
}

void AddCtlRCCodeEx(LPDLGITEMTEMPLATEEX pDlgItem, PWORD pClass, PWORD pTitle)
{
    printf("\tCONTROL ");
    if (*pTitle) {
         if (*pTitle == 0xFFFF) printf("%d", *(pTitle+1));
        else printf("\"%ls\"", pTitle);
    } else printf("NULL");
    printf(",%d,", pDlgItem->id);
    if (*pClass == 0xFFFF) printf("\"%ls\"", GetCtlClassW(*(pClass+1)));
    else printf("\"%ls\"", pClass);
    if (pDlgItem->style) printf(",0x%X", pDlgItem->style);
    else printf(",0");
    printf(",%d,%d,%d,%d,0x%X\n",
        pDlgItem->x, pDlgItem->y, pDlgItem->cx, pDlgItem->cy,
        pDlgItem->dwExtendedStyle);
}

void AddDlgCodeEx(LPDLGTEMPLATEEX pDlgEx, PWORD pMenu, PWORD pCaption)
{
    printf("hWnd=CreateWindowEx(");
    if (pDlgEx->exStyle) printf("0x%X", pDlgEx->exStyle);
    else printf("0");
    if (*pCaption) printf(",\"cDlg\",\"%ls\"", pCaption);
    else printf("NULL");
    printf(",0x%X,%d,%d,%d,%d,hWnd,(HMENU)%d,hInst,NULL);\n",
        pDlgEx->style, pDlgEx->x*2, pDlgEx->y*2, pDlgEx->cx*2, pDlgEx->cy*2,0);
}

void AddCtlCodeEx(LPDLGITEMTEMPLATEEX pDlgItem, PWORD pClass, PWORD pTitle)
{
    printf("\tCreateWindowEx(");
    if (pDlgItem->dwExtendedStyle) printf("0x%X", pDlgItem->dwExtendedStyle);
    else printf("0");
    if (*pClass == 0xFFFF) printf(",\"%ls\"", GetCtlClassW(*(pClass+1)));
    else printf(",\"%ls\"", pClass);
    if (*pTitle) {
         if (*pTitle == 0xFFFF) printf(",\"#%d\"", *(pTitle+1));
        else printf(",\"%ls\"", pTitle);
    } else printf("NULL");
    printf(",0x%X,%d,%d,%d,%d,hWnd,(HMENU)%d,hInst,NULL);\n",
        pDlgItem->style,
        pDlgItem->x*2, pDlgItem->y*2, pDlgItem->cx*2, pDlgItem->cy*2,
        pDlgItem->id);

}
May the source be with you