Work at SourceForge, help us to make it a better place! We have an immediate need for a Support Technician in our San Francisco or Denver office.

Close

raw_input() quick fix part II (DynaDialog.c)

Help
2006-02-06
2013-05-30
  • After modified builtin_raw_input(), add
    this DynaDialog.c to project. Then make it.

    /*------------ DynaDialog.c ------------*/
    //adapt from http://www.flipcode.org/cgi-bin/fcarticles.cgi?show=64064

    #include <windows.h>

    char* RawInputChar(char* prompt);
    LPCTSTR RawInputBox(LPCTSTR prompt);
    LRESULT CALLBACK RawInputBoxCB(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam);

    static DLGTEMPLATE* dialogTemplate;
    static int totalBufferLength;
    static int usedBufferLength;

    DLGTEMPLATE* DDLG_Template()
    {
            return dialogTemplate;
    }

    void DDLG_Free_DynamicDialog()
    {
            free(dialogTemplate);
    }

    static void EnsureSpace(int length)
    {
            if (length + usedBufferLength > totalBufferLength)
            {
                void* newBuffer;

                totalBufferLength += length * 2;

                newBuffer = malloc(totalBufferLength);
                memcpy(newBuffer, dialogTemplate, usedBufferLength);

                free(dialogTemplate);
                dialogTemplate = (DLGTEMPLATE*)newBuffer;
            }
    }

    static void AppendData(void* data, int dataLength)
    {
            EnsureSpace(dataLength);
            memcpy((char*)dialogTemplate + usedBufferLength, data, dataLength);
            usedBufferLength += dataLength;
    }

    static void AppendString(PCTSTR string)
    {
            int length = lstrlen(string) + 1;
            AppendData((void *)string, length * sizeof(WCHAR));
    }

    static void AlignData(int size)
    {
            int paddingSize = usedBufferLength % size;

            if (paddingSize != 0)
            {
                EnsureSpace(paddingSize);
                usedBufferLength += paddingSize;
            }
    }

    static void AddStandardComponent(WORD type, PCTSTR caption, DWORD style,
            DWORD exStyle, int x, int y, int w, int h, WORD id)
    {
            DLGITEMTEMPLATE item;
            WORD preType = 0xFFFF;

            // DWORD algin the beginning of the component data
            AlignData(sizeof(DWORD));

            item.style = style;
            item.x     = x;
            item.y     = y;
            item.cx    = w;
            item.cy    = h;
            item.id    = id;

            item.dwExtendedStyle = exStyle;

            AppendData(&item, sizeof(DLGITEMTEMPLATE));

            AppendData(&preType, sizeof(WORD));
            AppendData(&type, sizeof(WORD));

            AppendString(caption);

            // Increment the component count
            dialogTemplate->cdit++;
    }

    static void AddStatic(PCTSTR caption, DWORD style, DWORD exStyle, int x, int y,
           int w, int h, WORD id)
    {
            WORD creationDataLength = 0;
            AddStandardComponent(0x0082, caption, style, exStyle, x, y, w, h, id);
            AppendData(&creationDataLength, sizeof(WORD));
    }

    static void AddEditBox(PCTSTR caption, DWORD style, DWORD exStyle, int x, int y,
            int w, int h, WORD id)
    {
            WORD creationDataLength = 0;
            AddStandardComponent(0x0081, caption, style, exStyle, x, y, w, h, id);
            AppendData(&creationDataLength, sizeof(WORD));
    }

    static void AddButton(PCTSTR caption, DWORD style, DWORD exStyle, int x, int y,
            int w, int h, WORD id)
    {
            WORD creationDataLength = 0;
            AddStandardComponent(0x0080, caption, style, exStyle, x, y, w, h, id);
            AppendData(&creationDataLength, sizeof(WORD));
    }

    void DDLG_New_DynamicDialog(PCTSTR caption, DWORD style, int x, int y, int w, int h)
    {
            usedBufferLength = sizeof(DLGTEMPLATE );
            totalBufferLength = usedBufferLength;

            dialogTemplate = (DLGTEMPLATE*)malloc(totalBufferLength);
                    dialogTemplate->style = style;

            dialogTemplate->x     = x;
            dialogTemplate->y     = y;
            dialogTemplate->cx    = w;
            dialogTemplate->cy    = h;
            dialogTemplate->cdit  = 0;

            dialogTemplate->dwExtendedStyle = 0x80000000L;

            // The dialog box doesn't have a menu or a special class
            AppendData(_T("\0"), 2);
            AppendData(_T("\0"), 2);

            // Add the dialog's caption to the template
            AppendString(caption);
    }

    enum { INPUTBOX_MAXSTR=120, INPUTBOX_ID_TEXT=111 };
    typedef struct
    {
        TCHAR strData[INPUTBOX_MAXSTR+1];
        int strLen;
    }
    INPUTBOX_DATA;

    LRESULT CALLBACK RawInputBoxCB(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
    {
        static INPUTBOX_DATA* pData;

        switch (message)
        {
            case WM_INITDIALOG:
                pData = (INPUTBOX_DATA*) lParam;
                return TRUE;

            case WM_COMMAND:
                if (LOWORD(wParam) == IDOK) {
                    pData->strLen = GetDlgItemText(hDlg, INPUTBOX_ID_TEXT, pData->strData, INPUTBOX_MAXSTR);
                    EndDialog(hDlg, (int)pData);
                    return TRUE;
                }
                break;
        }
        return FALSE;
    }

    LPCTSTR RawInputBox(LPCTSTR prompt)
    {
        static INPUTBOX_DATA data;

        DDLG_New_DynamicDialog(_T("Input"), WS_CAPTION | WS_POPUP, 0, 0, 139, 58);

        AddStatic(prompt, WS_VISIBLE, 0, 7, 7, 125, 15, -1);
        AddEditBox(_T(""), WS_VISIBLE | WS_TABSTOP | ES_AUTOHSCROLL, WS_EX_STATICEDGE,
                7, 22, 125, 17, INPUTBOX_ID_TEXT);
        AddButton(_T("OK"), WS_VISIBLE | BS_DEFPUSHBUTTON, 0,
                7, 40, 36, 18, IDOK);
        DialogBoxIndirectParam(GetModuleHandle(0), DDLG_Template(), GetForegroundWindow(),
            (DLGPROC)RawInputBoxCB, (LPARAM)&data);

        DDLG_Free_DynamicDialog();
        return data.strData;
    }

    char* RawInputChar(char* prompt)
    {
        static char chData[INPUTBOX_MAXSTR+1];
        WCHAR wchData[INPUTBOX_MAXSTR+1];
        LPCTSTR input;
        BOOL usedDefChar;

        MultiByteToWideChar(CP_ACP, 0, prompt, -1, wchData, INPUTBOX_MAXSTR);

        input = RawInputBox(wchData);

        WideCharToMultiByte(CP_ACP, 0, input, -1, chData, INPUTBOX_MAXSTR, "?", &usedDefChar);
        return chData;
    }