飴屋ぷろじぇくと

 ちょっとカテゴリを分けてみようかなっと。

--.--.--[--] スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

2014.10.23[木] ダイアログリソースをFreeBASICのソースに変換するプログラム(全ソース公開)

掲題どおりです。
FbEditのリソースエディタかResEditの吐き出すRCファイルで、
ダイアログ一個+メニューだけという制限付きですが、だいたい変換できるはずです。

プログラムはBASICでなく何故かC++。
やっつけ仕事なのでコードはかなり汚いです。C++で一部にstd::string使ってるくせに文字列処理はほぼCのライブラリ関数でしかもバッファが最低限で固定長だったりと結構危ういプログラムなので(ないと思いますが)流用・使用する際は自己責任でお願いします。

fb-rc-file.png
↑こんなリソースから

fb-rc-dlg.png
最終的にリソース自体は使用せずに、こんなウィンドウを開くFBのソースを生成します。
前回の自作のライブラリは使用しません。ネイティブにWin32APIを使ったソースを生成します。生成したソースコードのコンパイルに元のリソースファイルは必要ありません。

下に掲載するソースとテンプレートと出力結果をよく見れば判りますが、殆どはテンプレートのコードで、プログラムから生成するのはウィンドウハンドル変数の宣言部と、ウィンドウの生成・初期化部分だけです。
これだけの画面を出すだけなのにすごいごちゃごちゃしたコードになります。プログラムのひな形としてこれはこれでありなんでしょうけど、ここまで自動で出来たとしても私はこんなコードをひな形になんかしたくありません。古典的なWindowsプログラムを作るのに理解しておいた方が良いコードなのは確かですが。(たぶん続く
rc2fb.cpp
 プログラム本体。コマンドラインで使用します。出力は標準出力に出ますので、
 rc2fb ファイル名.rc >ファイル名.bas
 のように使用します。
#include <windows.h>

#include <string.h>

#include <string>
using namespace std;

/*
 *  小文字にする。入力文字列を直接変更する
 */

char *strlowcase(char *s) {
    while (*s) {
        *s = tolower(*s);
        s++;
    }
    return s;
}

/*
 *  文字列の置き換えを行う。
 *  dst : 出力文字列  src : 入力文字列
 */

char *strreplace(char *dst, const char *src, const char *from, const char *to) {
    int l1 = strlen(from);
    int l2 = strlen(to);
    char *r = dst;
    const char *s = src;
    *dst = 0;
    const char *p;
    while ((p = strstr(s, from)) != NULL) {
        if (p > s) strncpy(r, s, p - s);
        r[p-s] = 0;
        r += p - s;
        s = p + l1;
        strcpy(r, to);
        r += l2;
    }
    strcpy(r, s);
    return dst;
}

char *ltrim(char *s) {
    char *t = s;
    char *u = s;
    while (*t == ' ' || *t == '\t') t++;
    while (*t) {
        *u++ = *t++;
    }
    *u = 0;
    return s;
}

/*
 *簡単にフォントを生成
 */

HFONT SetMyFont(HDC hdc, LPCTSTR face, int h, int angle = 0)
{
    HFONT hFont;
    hFont = CreateFont(h,    //フォント高さ
        0,                    //文字幅
        angle,                    //テキストの角度
        0,                    //ベースラインとx軸との角度
        FW_REGULAR,            //フォントの重さ(太さ)
        FALSE,                //イタリック体
        FALSE,                //アンダーライン
        FALSE,                //打ち消し線
        SHIFTJIS_CHARSET,    //文字セット
        OUT_DEFAULT_PRECIS,    //出力精度
        CLIP_DEFAULT_PRECIS,//クリッピング精度
        PROOF_QUALITY,        //出力品質
        FIXED_PITCH | FF_MODERN,//ピッチとファミリー
        face);    //書体名
    return hFont;
}
/*
 * デスクトップのフォントの縦横サイズを取得する
 * リソースからの座標・サイズの換算に使用する
 */

SIZE getUnitSize(int &h, char* face) {
    HWND hdtp = GetDesktopWindow();
    HDC dc = GetDC(hdtp);
    TEXTMETRIC txm;
    SIZE ret;
    int dpiY = GetDeviceCaps(dc, LOGPIXELSY);

    h = (h * dpiY / 36 + 1) / 2;
    HFONT hf = SetMyFont(dc, face, h);//Point To Pixels
    HGDIOBJ obj = SelectObject(dc, hf);
    //リソース単位の場合はこうする
    GetTextExtentPoint32(dc, "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz", 52, &ret);
    GetTextMetrics(dc, &txm);
    SelectObject(dc, obj);
    DeleteObject(hf);
    ReleaseDC(hdtp, dc);
    
    ret.cx = (ret.cx / 26 + 1) / 2;
    ret.cy = txm.tmHeight;

    return ret;
}



char buf[4096];

/*
 * スタイル値の文字列をBASIC用にC変換
 */

char* getstyle(char *wrk, char *p) {
    ltrim(p);
    if (*p == '0' && *(p+1) == 'x') {
        strcpy(wrk, "&H");
        strcat(wrk, p+2);
    } else if (strstr(p, "WS_") != NULL || strstr(p, "|") != NULL) {
        strreplace(buf, p, "|", "Or");
        strreplace(wrk, buf, "NOT ", "0 * ");
    } else {
        strcpy(wrk, p);
    }
    return wrk;
}

/*
 * 改行をカット
 */

char *strchomp(char *s) {
    char *p = strchr(s, '\n');
    if (p) *p = 0;//chomp
    return s;
}
//識別子文字か判別
int isNumAlpUnsc(char c) {
    return (c >= '0' && c <= '9' || c >= 'A' && c <= 'Z' || c >= 'a' && c <= 'z' || c == '_');
}
//単語単位でサーチ
char *srchWord(char *row, const char *word) {
    int ln = strlen(word);
    char *p = strstr(row, word);
    if (p) {
        while (p && (p > row && isNumAlpUnsc(*(p-1)) || isNumAlpUnsc(*(p+ln)))) {
            p = strstr(p+ln, word);
        }    
    }
    return p;
}
/*
 * コントロール汎用整形プロシージャ
 * patten 0 ボタン等  1 エディット等  2 "CONTROL"
 * decl 変数宣言を出力
 * impl 初期化等のコードを出力
 */

void control(int pattern, char *p, char *cls, char *defstyle, char*dnm, SIZE *unit, string &decl, string &impl) {
    int left = 0, top = 0, width = 0, height = 0;
    char buf[256], wrk3[128], wrk4[128], cnm[64], cln[64];
    ltrim(p);
    char *txt, *id, *sty;
    if (pattern == 0) {
        txt = "\"\"";
        id =  strtok(p, ",");
    } else {
        txt = strtok(p, ",");
        id =  strtok(NULL, ",");
    }
    ltrim(id);
    if (pattern == 2) {
        cls = strtok(NULL, ",");
        ltrim(cls);
        sty = strtok(NULL, ",");
    }
    if (strstr(cls, "WC_") != NULL || *cls == '"') {
        strcpy(cln, cls);
    } else {
        strcpy(cln, "\"");
        strcat(cln, cls);
        strcat(cln, "\"");
    }
    char *px =  strtok(NULL, ",");
    ltrim(px); sscanf(px, "%d", &left);
    px =  strtok(NULL, ",");
    ltrim(px); sscanf(px, "%d", &top);
    px =  strtok(NULL, ",");
    ltrim(px); sscanf(px, "%d", &width);
    px =  strtok(NULL, ",");
    ltrim(px); sscanf(px, "%d", &height);
    
    if (pattern != 2) {
        sty =  strtok(NULL, ",");
    }
    ltrim(sty);
    
    getstyle(wrk3, sty);
    
    char *exsty =  strtok(NULL, "\n");
    if (exsty) {
        ltrim(exsty);
        getstyle(wrk4, exsty);
    } else {
        strcpy(wrk4, "0");
    }
    
    strcpy(cnm, id);
    if (!strncmp(cnm, "IDC_", 4)) {
        strcpy(cnm, id + 4);
        strlowcase(cnm);
    }
    if (!strcmp(cnm, "IDOK")) {
        strcpy(cnm, "btnOK");
    } else if (!strcmp(cnm, "IDCANCEL")) {
        strcpy(cnm, "btnCancel");
    }
    sprintf(buf, "Dim Shared %s As HWND\n", cnm);
    decl += buf;
    sprintf(buf,"%s = CreateWindowEx(%s,%s,%s, %s Or %s,%d,%d,%d,%d,%s,NULL,hInst,0)\n"
                                              , cnm
                                              , wrk4
                                              , cln
                                              , txt
                                              , defstyle
                                              , wrk3
                                              , left * unit->cx / 4
                                              , top * unit->cy / 8
                                              , width * unit->cx / 4
                                              , height * unit->cy / 8
                                              , dnm);
    impl += buf;
    sprintf(buf,"SendMessage(%s, WM_SETFONT, Cast(WPARAM, fFont), 1)\n", cnm);
    impl += buf;
}
/*
 * メニューリソーススクリプト変換処理(再帰してます)
 */

void procmenu(char *p, char *mnm, string &decl, string &impl, FILE *f, int dep = 0) {
    char row[256];
    char mn[64];
    int i = 10, j = 1;
    if (dep > 0) {
        sprintf(mn, "%s%d", mnm, dep);
    } else {
        strcpy(mn, mnm);
    }
    sprintf(buf, "Dim Shared %s As HMENU\n", mn);
    decl += buf;
    sprintf(buf, "%s = CreateMenu()\n", mn);
    decl += buf;
    
    if (fgets(row, sizeof(row), f)) {
        if (srchWord(row, "BEGIN") != NULL || strchr(row, '{') != NULL) {
            while(fgets(row, sizeof(row), f)) {
                strchomp(row);
                if (srchWord(row, "MENUITEM SEPARATOR") != NULL) {
                    sprintf(buf, "AppendMenu(%s, MF_SEPARATOR, 0, NULL)\n", mn);
                    impl += buf;
                } else if ((p = srchWord(row, "MENUITEM")) != NULL) {
                    p += 9;
                    char *txt = strtok(p, ",");
                    ltrim(txt);
                    char *id = strtok(NULL, ",");
                    ltrim(id);
                    sprintf(buf, "Const %s As Integer = %d\n", id, 10000 + dep * 10 + j++);
                    decl += buf;
                    sprintf(buf, "AppendMenu(%s, MF_STRING, %s, %s)\n", mn, id, txt);
                    impl += buf;
                } else if ((p = srchWord(row, "POPUP")) != NULL) {
                    p += 5;
                    ltrim(p);
                    procmenu(p, mnm, decl, impl, f, dep+i);
                    sprintf(buf, "AppendMenu(%s, MF_POPUP, Cast(ULong, %s%d), %s)\n", mn, mnm, dep+i, p);
                    impl += buf;
                    i++;
                } else if (srchWord(row, "END") != NULL || strchr(row, '}') != NULL) {
                    break;
                }
            }
        }
    }
}

/*
 * メイン関数
 * ・リファクタリングが十分でなく、読めないコード
 * ・ダイアログリソースが一つだけ存在するRCでないと正常動作しない
 * ・Menu未実装
 */

int main(int argc, char *argv[]) {
    char row[256];
    FILE *f = fopen(argv[1], "rt");
    SIZE unit;
    int ncw = GetSystemMetrics(SM_CXFRAME) * 2;
    int nch = GetSystemMetrics(SM_CYFRAME) * 2 + GetSystemMetrics(SM_CYSIZE);
    int cym = GetSystemMetrics(SM_CYMENU);
    int ncm = 0;
    
    string decl;
    string impl;
    string menu;
    
    int dlg = 0;
    char cap[128];
    char fnt[64], did[64], dnm[64], cnm[64], mnm[64];
    char wrk[128],wrk2[128],wrk3[128],wrk4[128];
    int style, exstyle;
    char *p;
    
    if (!f) {
        printf("ファイルが開けません\n");
        return -1;
    }
    
    while (fgets(row, sizeof(row), f)) {
        strchomp(row);
        if (*row == '#') continue;
        if ((p = srchWord(row, "DIALOGEX")) != NULL || (p = srchWord(row, "DIALOG")) != NULL) {
            decl += "' declare dialog\n";
            impl += "'
dialog\n"
;
            int x, y, h, w, fh;
            char *str_style = wrk, *str_exstyle = wrk2;
            strcpy(wrk, "0");
            strcpy(wrk2, "0");
            style = 0;
            exstyle = 0;
            *(p-1) = 0;
            strcpy(did, row);
            p += 6;
            if (*p == 'E') p += 2;
            sscanf(p, "%d,%d,%d,%d",&x,&y,&w,&h);
            strcpy(mnm, "NULL");
            
            while(fgets(row, sizeof(row),f)) {
                strchomp(row);
                if (*row == 0) break;
                if ((p = srchWord(row, "STYLE")) != NULL) {
                    str_style = getstyle(wrk, p+5);
                } else if ((p = srchWord(row, "CAPTION")) != NULL) {
                    strcpy(cap, p+7);
                    ltrim(cap);
                } else if ((p = srchWord(row, "FONT")) != NULL) {
                    p = strtok(p+5, ",");
                    sscanf(p, "%d", &fh);
                    p = strtok(NULL, ",");
                    ltrim(p);
                    if (*p == '"') p++;
                    strcpy(fnt, p);
                    p = strchr(fnt,'"');
                    if (p) *p = 0;
                } else if ((p = srchWord(row, "MENU")) != NULL) {
                    p += 4;
                    ltrim(p);
                    strcpy(mnm, p);
                    if (!strncmp(mnm, "IDR_", 4)) {
                        strcpy(mnm, p + 4);
                        strlowcase(mnm);
                    }
                    ncm += cym;
                } else if ((p = srchWord(row, "EXSTYLE")) != NULL) {
                    str_exstyle = getstyle(wrk2, p+7);
                } else if ((p = srchWord(row, "BEGIN")) != NULL || (p = strchr(row, '{')) != NULL) {
                    unit = getUnitSize(fh, fnt);
                    strcpy(dnm, did);
                    if (!strncmp(dnm, "IDD_", 4)) {
                        strcpy(dnm, did + 4);
                        strlowcase(dnm);
                    }
                    //sprintf(buf, "Dim Shared %s As Dialog\n", dnm);
                    sprintf(buf, "Dim Shared %s As HWND\n", dnm);
                    decl += buf;
                    //sprintf(buf, "%s.Load(%s)\n", dnm, did);
                    sprintf(buf, "%s = CreateWindowEx(%s,@TheClassName,%s,%s,%d,%d,%d,%d,NULL,%s,hInst,0)\n"
                                                                , dnm
                                                                , str_exstyle
                                                                , cap
                                                                , str_style
                                                                , x * unit.cx / 4
                                                                , y * unit.cy / 8
                                                                , w * unit.cx / 4 + ncw
                                                                , h * unit.cy / 8 + nch + ncm
                                                                , mnm);
                    impl += buf;
                    sprintf(buf, "Dim fFont As HFONT = EasyFont(\"%s\",%d)\n", fnt, fh);
                    impl += buf;
                    //Controls
                    while(fgets(row, sizeof(row),f)) {
                        if ((p = srchWord(row, "PUSHBUTTON")) != NULL) {
                            control(1, p + 10, "button",
                                    "BS_PUSHBUTTON Or WS_CHILD Or WS_VISIBLE Or WS_TABSTOP",
                                    dnm, &unit, decl, impl);
                        } else if ((p = srchWord(row, "DEFPUSHBUTTON")) != NULL) {
                            control(1, p + 13, "button",
                                    "BS_DEFPUSHBUTTON Or WS_CHILD Or WS_VISIBLE Or WS_TABSTOP",
                                    dnm, &unit, decl, impl);
                        } else if ((p = srchWord(row, "AUTOCHECKBOX")) != NULL) {
                            control(1, p + 12, "button",
                                    "BS_AUTOCHECKBOX Or WS_CHILD Or WS_VISIBLE Or WS_TABSTOP",
                                    dnm, &unit, decl, impl);
                        } else if ((p = srchWord(row, "AUTORADIOBUTTON")) != NULL) {
                            control(1, p + 15, "button",
                                    "BS_AUTORADIOBUTTON Or WS_CHILD Or WS_VISIBLE Or WS_TABSTOP",
                                    dnm, &unit, decl, impl);
                        } else if ((p = srchWord(row, "GROUPBOX")) != NULL) {
                            control(1, p + 8, "button",
                                    "BS_GROUPBOX Or WS_CHILD Or WS_VISIBLE",
                                    dnm, &unit, decl, impl);
                        } else if ((p = srchWord(row, "EDITTEXT")) != NULL) {
                            control(0, p + 8, "edit",
                                    "WS_CHILD Or WS_VISIBLE Or WS_TABSTOP",
                                    dnm, &unit, decl, impl);
                        } else if ((p = srchWord(row, "LTEXT")) != NULL) {
                            control(1, p + 5, "static",
                                    "WS_CHILD Or WS_VISIBLE",
                                    dnm, &unit, decl, impl);
                        } else if ((p = srchWord(row, "LISTBOX")) != NULL) {
                            control(0, p + 7, "listbox",
                                    "WS_CHILD Or WS_VISIBLE",
                                    dnm, &unit, decl, impl);
                        } else if ((p = srchWord(row, "COMBOBOX")) != NULL) {
                            control(0, p + 8, "combobox",
                                    "WS_CHILD Or WS_VISIBLE Or WS_TABSTOP",
                                    dnm, &unit, decl, impl);
                        } else if ((p = strstr(row, "CONTROL")) != NULL) {
                            control(2, p + 7, "",
                                    "WS_CHILD Or WS_VISIBLE Or WS_TABSTOP",
                                    dnm, &unit, decl, impl);
                        } else if (strstr(row, "END") != NULL || strchr(row, '}') != NULL) {
                            break;
                        }
                    }
                }
            }
        } else if ((p = srchWord(row, "MENU")) != NULL) {
            decl += "' declare menu\n";
            impl += "'
menu\n"
;
            int n = decl.size() - 1;
            p = strtok(row, " ");
            strcpy(mnm, p);
            if (!strncmp(mnm, "IDR_", 4)) {
                strcpy(mnm, p + 4);
                strlowcase(mnm);
            }
            
            procmenu(p+4, mnm, decl, impl, f, 0);
        }
    }
    fclose(f);

    FILE *fin = fopen("template.bas", "rt");
    fseek(fin, 0, SEEK_END);
    int n = ftell(fin);
    fseek(fin, 0, SEEK_SET);
    char *buf = new char[n+1024];
    fread(buf, 1, n, fin);
    fclose(fin);

    sprintf(row, "DrawMenuBar(%s)\nShowWindow(%s, SW_SHOWNORMAL)\n", dnm, dnm);
    printf(buf, decl.c_str(), impl.c_str(), row);
}

template.bas コンパイル後の上記プログラムと同じディレクトリに置いてください。
#define UNICODE
#include once "windows.bi"
#include once "win/commctrl.bi"

Function EasyFont(face As String, h As Long, angle As Long = 0) As HFONT
    Dim As HWND hdtp = GetDesktopWindow()
    Dim As HDC dc = GetDC(hdtp)
    Dim As Long dpiY = GetDeviceCaps(dc, LOGPIXELSY)
    ReleaseDC(hdtp, dc)
    Return CreateFont(h * dpiY \ 72, 0, angle, 0, _
                    FW_REGULAR, FALSE, FALSE, FALSE, _
                    SHIFTJIS_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, _
                    PROOF_QUALITY, FIXED_PITCH Or FF_MODERN, face)
End Function

Dim Shared hInst As HINSTANCE
hInst = GetModuleHandle(NULL)

Declare Function TheWindowProc(ByVal hWin As HWND, ByVal uMsg As UINT, ByVal wp As WPARAM, ByVal lp As LPARAM) As Integer
Declare Function OnCreate(ByVal hWin As HWND, ByVal uMsg As UINT, ByVal wp As WPARAM, ByVal lp As LPARAM) As Long
Declare Function OnCommand(ByVal hWin As HWND, ByVal uMsg As UINT, ByVal wp As WPARAM, ByVal lp As LPARAM) As Long
Declare Function OnClose(ByVal hWin As HWND, ByVal uMsg As UINT, ByVal wp As WPARAM, ByVal lp As LPARAM) As Long
Declare Function OnDestroy(ByVal hWin As HWND, ByVal uMsg As UINT, ByVal wp As WPARAM, ByVal lp As LPARAM) As Long

Dim wc As WNDCLASSEX
Dim Shared TheClassName As WString * 20 = "MY_FORM_CLS_NAME"

wc.cbSize        = sizeof(WNDCLASSEX)
wc.style         = CS_DBLCLKS
wc.lpfnWndProc   = @TheWindowProc
wc.cbClsExtra    = 0
wc.cbWndExtra    = DLGWINDOWEXTRA
wc.hInstance     = hInst
wc.hIcon         = Cast(HICON, LoadImage(NULL, IDI_APPLICATION, IMAGE_ICON, 0, 0, LR_SHARED))
wc.hCursor       = Cast(HCURSOR, LoadImage(NULL, IDC_ARROW, IMAGE_CURSOR, 0, 0, LR_SHARED))
wc.hbrBackground = Cast(HBRUSH, GetStockObject(WHITE_BRUSH))
wc.lpszMenuName  = NULL
wc.lpszClassName = @TheClassName
wc.hIconSm       = Cast(HICON, LoadImage(NULL, IDI_APPLICATION, IMAGE_ICON, 0, 0, LR_SHARED))

RegisterClassEx @wc

Function TheWindowProc(ByVal hWin As HWND,ByVal uMsg As UINT,ByVal wp As WPARAM,ByVal lp As LPARAM) As Integer
    Dim ret As Long
    Select Case uMsg
    Case WM_CREATE
        ret = OnCreate(hWin, uMsg, wp, lp)
    Case WM_COMMAND
        ret = OnCommand(hWin, uMsg, wp, lp)
    Case WM_CLOSE
        ret = OnClose(hWin, uMsg, wp, lp)
    Case WM_DESTROY
        ret = OnDestroy(hWin, uMsg, wp, lp)
    End Select
    if ret = 0 Then
        ret = DefWindowProc(hWin, uMsg, wp, lp)
    End If
    Return ret
End Function

%s
Function OnCreate(ByVal hWin As HWND, ByVal uMsg As UINT, ByVal wp As WPARAM, ByVal lp As LPARAM) As Long
    Return 0
End Function

Function OnCommand(ByVal hWin As HWND, ByVal uMsg As UINT, ByVal wp As WPARAM, ByVal lp As LPARAM) As Long
    Return 0
End Function

Function OnClose(ByVal hWin As HWND, ByVal uMsg As UINT, ByVal wp As WPARAM, ByVal lp As LPARAM) As Long
    PostQuitMessage(0)
    Return 0
End Function

Function OnDestroy(ByVal hWin As HWND, ByVal uMsg As UINT, ByVal wp As WPARAM, ByVal lp As LPARAM) As Long
    Return 0
End Function

%s
%s
' Message loop
Dim mMsg As MSG
Do While GetMessage(@mMsg,NULL,0,0)
    TranslateMessage(@mMsg)
    DispatchMessage(@mMsg)
Loop

変換後のソース
#define UNICODE
#include once "windows.bi"
#include once "win/commctrl.bi"

Function EasyFont(face As String, h As Long, angle As Long = 0) As HFONT
    Dim As HWND hdtp = GetDesktopWindow()
    Dim As HDC dc = GetDC(hdtp)
    Dim As Long dpiY = GetDeviceCaps(dc, LOGPIXELSY)
    ReleaseDC(hdtp, dc)
    Return CreateFont(h * dpiY \ 72, 0, angle, 0, _
                    FW_REGULAR, FALSE, FALSE, FALSE, _
                    SHIFTJIS_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, _
                    PROOF_QUALITY, FIXED_PITCH Or FF_MODERN, face)
End Function

Dim Shared hInst As HINSTANCE
hInst = GetModuleHandle(NULL)

Declare Function TheWindowProc(ByVal hWin As HWND, ByVal uMsg As UINT, ByVal wp As WPARAM, ByVal lp As LPARAM) As Integer
Declare Function OnCreate(ByVal hWin As HWND, ByVal uMsg As UINT, ByVal wp As WPARAM, ByVal lp As LPARAM) As Long
Declare Function OnCommand(ByVal hWin As HWND, ByVal uMsg As UINT, ByVal wp As WPARAM, ByVal lp As LPARAM) As Long
Declare Function OnClose(ByVal hWin As HWND, ByVal uMsg As UINT, ByVal wp As WPARAM, ByVal lp As LPARAM) As Long
Declare Function OnDestroy(ByVal hWin As HWND, ByVal uMsg As UINT, ByVal wp As WPARAM, ByVal lp As LPARAM) As Long

Dim wc As WNDCLASSEX
Dim Shared TheClassName As WString * 20 = "MY_FORM_CLS_NAME"

wc.cbSize        = sizeof(WNDCLASSEX)
wc.style         = CS_DBLCLKS
wc.lpfnWndProc   = @TheWindowProc
wc.cbClsExtra    = 0
wc.cbWndExtra    = DLGWINDOWEXTRA
wc.hInstance     = hInst
wc.hIcon         = Cast(HICON, LoadImage(NULL, IDI_APPLICATION, IMAGE_ICON, 0, 0, LR_SHARED))
wc.hCursor       = Cast(HCURSOR, LoadImage(NULL, IDC_ARROW, IMAGE_CURSOR, 0, 0, LR_SHARED))
wc.hbrBackground = Cast(HBRUSH, GetStockObject(WHITE_BRUSH))
wc.lpszMenuName  = NULL
wc.lpszClassName = @TheClassName
wc.hIconSm       = Cast(HICON, LoadImage(NULL, IDI_APPLICATION, IMAGE_ICON, 0, 0, LR_SHARED))

RegisterClassEx @wc

Function TheWindowProc(ByVal hWin As HWND,ByVal uMsg As UINT,ByVal wp As WPARAM,ByVal lp As LPARAM) As Integer
    Dim ret As Long
    Select Case uMsg
    Case WM_CREATE
        ret = OnCreate(hWin, uMsg, wp, lp)
    Case WM_COMMAND
        ret = OnCommand(hWin, uMsg, wp, lp)
    Case WM_CLOSE
        ret = OnClose(hWin, uMsg, wp, lp)
    Case WM_DESTROY
        ret = OnDestroy(hWin, uMsg, wp, lp)
    End Select
    if ret = 0 Then
        ret = DefWindowProc(hWin, uMsg, wp, lp)
    End If
    Return ret
End Function

' declare menu
Dim Shared menu1 As HMENU
menu1 = CreateMenu()
Dim Shared menu110 As HMENU
menu110 = CreateMenu()
Const IDM_QUIT As Integer = 10101
' declare dialog
Dim Shared dialog1 As HWND
Dim Shared btnCancel As HWND
Dim Shared btnOK As HWND

Function OnCreate(ByVal hWin As HWND, ByVal uMsg As UINT, ByVal wp As WPARAM, ByVal lp As LPARAM) As Long
    Return 0
End Function

Function OnCommand(ByVal hWin As HWND, ByVal uMsg As UINT, ByVal wp As WPARAM, ByVal lp As LPARAM) As Long
    Return 0
End Function

Function OnClose(ByVal hWin As HWND, ByVal uMsg As UINT, ByVal wp As WPARAM, ByVal lp As LPARAM) As Long
    PostQuitMessage(0)
    Return 0
End Function

Function OnDestroy(ByVal hWin As HWND, ByVal uMsg As UINT, ByVal wp As WPARAM, ByVal lp As LPARAM) As Long
    Return 0
End Function

' menu
AppendMenu(menu110, MF_STRING, IDM_QUIT, "閉じる(&Q)")
AppendMenu(menu1, MF_POPUP, Cast(ULong, menu110), "ファイル(&F)")
' dialog
dialog1 = CreateWindowEx(WS_EX_WINDOWEDGE,@TheClassName,"Dialog",DS_3DLOOK Or DS_CENTER Or DS_SHELLFONT Or WS_CAPTION Or WS_VISIBLE Or WS_POPUP Or WS_THICKFRAME Or WS_SYSMENU,0,0,295,188,NULL,menu1,hInst,0)
Dim fFont As HFONT = EasyFont("Ms Shell Dlg",11)
btnCancel = CreateWindowEx(WS_EX_LEFT,"button","キャンセル", BS_PUSHBUTTON Or WS_CHILD Or WS_VISIBLE Or WS_TABSTOP Or 0,193,33,75,19,dialog1,NULL,hInst,0)
SendMessage(btnCancel, WM_SETFONT, Cast(WPARAM, fFont), 1)
btnOK = CreateWindowEx(WS_EX_LEFT,"button","OK", BS_DEFPUSHBUTTON Or WS_CHILD Or WS_VISIBLE Or WS_TABSTOP Or 0,193,9,75,19,dialog1,NULL,hInst,0)
SendMessage(btnOK, WM_SETFONT, Cast(WPARAM, fFont), 1)

DrawMenuBar(dialog1)
ShowWindow(dialog1, SW_SHOWNORMAL)

' Message loop
Dim mMsg As MSG
Do While GetMessage(@mMsg,NULL,0,0)
    TranslateMessage(@mMsg)
    DispatchMessage(@mMsg)
Loop

こちらに掲載したソースコードの使用・転載等は自由にしていただいて構いませんが、コードの品質・プログラムの動作不具合や使用を因とするあらゆる不利益を当方は一切保証しません。あくまで自己責任でお願いします。

Comment






(編集・削除用)

Trackback

http://utau2009.blog114.fc2.com/tb.php/22-13bba189

この記事にトラックバック(FC2Blog User)

Copyright © 飴屋/菖蒲

上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。