fc2ブログ

飴屋ぷろじぇくと

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

2014.10.28[火]  WindowsリソースからFreeBASIC+GTK(その2)

gtk-app-dlg.png
対応を増やしてみました。
スタティックテキスト → GtkLabel
イメージ → GtkImage
ボタン → GtkButton
チェックボックスのボタン風表示 → GtkToggleButton
チェックボックス → GtkCheckButton
ラジオボタン → GtkRadioButton
エディット → GtkEntry
複数行エディット → GtkTextView
リストボックス → GtkTreeViewで一列のリストを作成
ドロップダウン → GtkComboBoxEntry
ドロップダウンリスト → GtkComboBox
プログレスバー → GtkProgressBar
オーナードローなスタティック → GtkDrawingArea
※各ウィジット毎の出力コードの利用法はGTKの勉強兼ねてまた記事にしようと思います。

あと、出力先に指定したファイルが存在する場合、事前に読み込んで編集済みのイベントプロシージャやユーザーが追加した関数などを保存して再出力するようにしました。つまり、
>rc2fbgtk test.rc test.bas
などどして、出力したソースファイルに、
Sub dialog1_destroy Cdecl (ByVal widget As GtkWidget Ptr, ByVal gdata As gpointer)
'右上の×ボタンでウィンドウを閉じたときアプリケーションが終了するようにする
gtk_main_quit()

End Sub
こんな風にコードを変更(斜体部)した後リソースを変更してもう一度上書き変換したとしても、追記したコードは消えることなく出力ファイルに引き継がれるということです。
その他:
・自動で出力されるイベントプロシージャと関係なく追加した関数等も同様に引き継がれます。
・Namespaceで囲んだ範囲も保存します。
・モジュールレベルの変数宣言は保存されません。消えます。
・Sub Initalize() というプロシージャを書いておくと初期化時に自動的に呼び出してくれます。
・「ウィジットの変数名_シグナル名」でイベントプロシージャを書いておくと、自動でg_signel_connectのコードを挿入してくれます。引数やシグナル名は検査しないので間違えるとコンパイルエラーやランタイムエラーになります。
不具合注意!:同名の手続きがあると引数が違ってもどれか一つを残して消えてしまいます。

最後のが未解決ですが、これでとりあえずプログラミングできるはず。

機能が複雑化してきたのでいつか改めて使い方の記事は書く予定です。
今回はソースコードまで。
rc2fbgtk.cpp
/*

コンパイル:

[GTK+パスは環境に合わせて設定]

set GTK=C:\gtk+2.24.10_win32

[gccの場合]

g++ -o rc2fbgtk rc2fbgtk.cpp -I"%GTK%/include\gtk-2.0" -I"%GTK%/include\glib-2.0" -I"%GTK%/lib\glib-2.0\include" -I"%GTK%/include\cairo" -I"%GTK%/include\pango-1.0" -I"%GTK%/lib\gtk-2.0\include" -I"%GTK%/include\gdk-pixbuf-2.0" -I"%GTK%/include\atk-1.0" -L"%GTK%/lib" -lgdk-win32-2.0 -lgtk-win32-2.0 -lglib-2.0 -lgobject-2.0 -lcairo -static -mms-bitfields

[msvcの場合]

cl -Fe"rc2fbgtk" rc2fbgtk.cpp -I"%GTK%/include\gtk-2.0" -I"%GTK%/include\glib-2.0" -I"%GTK%/lib\glib-2.0\include" -I"%GTK%/include\cairo" -I"%GTK%/include\pango-1.0" -I"%GTK%/lib\gtk-2.0\include" -I"%GTK%/include\gdk-pixbuf-2.0" -I"%GTK%/include\atk-1.0" user32.lib gdi32.lib -link -libpath:"%GTK%\lib" gdk-win32-2.0.lib gtk-win32-2.0.lib glib-2.0.lib gobject-2.0.lib cairo.lib


使用例:※実行時はGTKのbinディレクトリにパスを通しておく必要があります。

rc2fbgtk test.rc output.bas

fbc output.bas -p %GTK%\lib

output.exe

*/


//#if defined(_MSC_VER) && defined(_WIN32)
#include <windows.h>
//#endif

#include <gtk/gtk.h>

#include <stdio.h>
#include <string.h>

#include <string>
#include <vector>
#include <map>
using namespace std;


char buf[4096];
char row[1024];

typedef struct {
    string decl; //一般宣言
    string impl; //実装
    string menu; //メニュー
    map<string,string> procs; //手続き等保管
    map<string,string> widgets; //ウィジット変数の宣言
    map<string,string> dclproc; //手続き宣言
    map<string,string> signals; //シグナルイベント設定
} CodeData;

void signalgen(CodeData *cds, const char *name, const char *sig);

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

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

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

char *strtoupper(char *s) {
    while (*s) {
        *s = toupper(*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 *strltrim(char *s) {
    char *t = s;
    char *u = s;
    while (*t == ' ' || *t == '\t') t++;
    while (*t) {
        *u++ = *t++;
    }
    *u = 0;
    return s;
}
/*
* 右トリム:文字列の右側の空白を削除する
*  入力文字列を変更します
*/

char *strrtrim(char *s) {
    int n = strlen(s);
    if (n > 0) {
        char *t = s + n - 1;
        while (*t == ' ' || *t == '\t') *t-- = 0;
    }
    return s;
}
/*
* 改行をカット
*  入力文字列を変更します
*/

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 == '_');
}
/*
* 単語単位でサーチ
* strstrを利用して楽してるので効率は悪い
*/

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;
}

//TODO:切り替えが中途半端。GDI32使うならGTKは必要ないが……
#if defined(_MSC_VER) && defined(_WIN32)
/*
*簡単にフォントを生成
*/

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);
//printf("'dpiY=%d\n", dpiY);
    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);
//printf("'cx=%d cy=%d\n", ret.cx,ret.cy);
    GetTextMetrics(dc, &txm);
    SelectObject(dc, obj);
    DeleteObject(hf);
    ReleaseDC(hdtp, dc);
    
    ret.cx = (ret.cx / 26 + 1) / 2;
    ret.cy = txm.tmHeight;
//printf("'cx=%d cy=%d\n", ret.cx,ret.cy);
    return ret;
}
#else

//TODO:……GTKのみにしてWindows.hを外すのはコントロールのクラス名の関係で出来なかった。

/*
typedef struct size_win {
    int cx, xy;
} SIZE;
*/

SIZE getUnitSize(int fontsize, char* fontfamily)
{
    cairo_t *cr;
    cairo_surface_t *surface;
    GdkScreen *screen = gdk_screen_get_default();
    float dpi = gdk_screen_get_resolution(screen);
    double size;
    SIZE ret;
    
    cairo_font_extents_t extents;
    cairo_text_extents_t text_extents;

    surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, 200, 200);
    cr = cairo_create(surface);


    cairo_select_font_face(cr, fontfamily, CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL);
    
    if (dpi < 0) dpi = 96.0;
    size = fontsize * (dpi/72.0);

    cairo_set_font_size(cr, size);

    cairo_font_extents(cr, &extents);
    cairo_text_extents(cr, "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz", &text_extents);

    ret.cx = (text_extents.width / 26 + 1) / 2;
    ret.cy = extents.height;
    //*descent = extents.descent;

    cairo_destroy(cr);
    cairo_surface_destroy(surface);

    return ret;
}

#endif


char decline[512];
/*
*出力先ファイルから手続きを読み込んで手続き宣言(Declare)を作ったりする
*/

int getProcCodes(CodeData *cds, const string &filename) {
    FILE *fin = fopen(filename.c_str(), "rt");
    char sts[64];
    char org[64];
    if (!fin) return -1;
    char *p, *q;
    while (fgets(row, sizeof(row), fin)) {
        strcpy(buf, row);
        strtolower(buf);
        if (!srchWord(buf, "declare") && !srchWord(buf, "end") &&
                 ((p = srchWord(buf, "sub")) != NULL || (p = srchWord(buf, "function")) != NULL || (p = srchWord(buf, "namespace")) != NULL)) {
            q = strchr(p, ' ');
            strncpy(sts, p, q-p);
            sts[q-p] = 0;
            strltrim(q);
            string proc = strtok(q, " (\n");
            
            strcpy(decline, row);
            strncpy(org, row + (q - buf), 64);
            org[63] = 0;
            
            string code = "";
            while (!feof(fin)) {
                code += row;
                if (strstr(buf, "end") && strstr(buf, sts)) break;
                fgets(row, sizeof(row), fin);
                strcpy(buf, row);
                strtolower(buf);
            }
            cds->procs[proc] = code + "\n";
            
            strltrim(org);
            strtok(org, " (\n");
            p = strchr(org, '_');
            if (p > org && *(p+1) != 0) { // _ の前後がある
                *p = 0;
                p++;
                strcpy(sts, org);
                strtolower(sts);
                if (cds->widgets.find(sts) != cds->widgets.end()) {//変数宣言と_の前が一致するものは
                    while ((q = strchr(p, '_')) != NULL) *q = '-';
                    signalgen(cds, org, p);
                    if (cds->dclproc.find(proc) == cds->dclproc.end()) {
                        sprintf(buf, "Declare %s", decline);
                        cds->dclproc[proc] = buf;
                    }
                }
            }
        }
    }
    fclose(fin);
    return 0;
}

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

char* getstyle(char *wrk, char *p) {
    strltrim(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;
}
/*
* スタイル値を数値表現と見なしてflagが立ってるか調べる
*/

int chknumstyle(const char *sty, unsigned int flag) {
    if (sty && *sty) {
        int f = 0;
        if (*sty == '0' && *(sty+1) == 'x') {
            sscanf(sty + 2, "%x", &f);
        } else if (isdigit(*sty)) {
            sscanf(sty, "%d", &f);
        }
        return (f & flag) == flag;
    }
    return 0;
}
/*
* GtkWidget変数の宣言を生成してコードデータ構造体に登録する
*/

void widgetValueGen(CodeData *cds, const char *dnm) {
    char lnm[64];
    sprintf(buf, "Dim Shared %s As GtkWidget Ptr\n", dnm);
    strcpy(lnm, dnm);
    strtolower(lnm);
    cds->widgets[lnm] = buf;
}
/*
*g_signal_connectを生成する
*/

void signalgen(CodeData *cds, const char *name, const char *sig) {
    char namsig[64];
    char key[64];
    char *p;
    sprintf(namsig, "%s_%s", name, sig);
    while((p = strchr(namsig, '-')) != NULL) *p = '_';
    strcpy(key, namsig);
    strtolower(key);
    if (cds->signals.find(key) == cds->signals.end()) {
        sprintf(buf, "g_signal_connect(G_OBJECT(%s), \"%s\", G_CALLBACK(@%s), NULL)\n", name, sig, namsig);
        cds->signals[key] = buf;
    }
}
/*
* シグナルコールバックを生成
*/

void procgen(const char *cnm, const char *enm, CodeData *cds, const char *codes = NULL) {
    char name[128];
    sprintf(name, "%s_%s", cnm, enm);
    strtolower(name);
    sprintf(buf, "Declare Sub %s_%s Cdecl (ByVal widget As GtkWidget Ptr, gdata As gpointer)\n", cnm, enm);
    cds->dclproc[name] = buf;
    if (cds->procs.find(name) == cds->procs.end()) {
        string code;
        sprintf(buf, "Sub %s_%s Cdecl (ByVal widget As GtkWidget Ptr, ByVal gdata As gpointer)\n", cnm, enm);
        code += buf;
        if (codes == NULL) {
            code += "\t'Please write your codes here.\n";
        } else {
            code += codes;
        }
        code += "End Sub\n\n";
        cds->procs[name] = code;
    }
}
/*
* コントロール汎用整形プロシージャ
* patten 0 ボタン等  1 エディット等  2 "CONTROL"
* decl 変数宣言を出力
* impl 初期化等のコードを出力
** TODO: 構成データとコード生成部を分離する **
*/

int m_radios = 0;
int m_static = 0;
int m_liststore = 0;
void control(int pattern, char *p, const char *cls, const char *defstyle, char*dnm, SIZE *unit, CodeData *cds) {
    int left = 0, top = 0, width = 0, height = 0;
    char buf[256], wrk3[256], wrk4[160], cnm[64], cln[64];
    strltrim(p);
    const char *txt;
    char *id, *sty;
    if (pattern == 0) {
        txt = "\"\"";
        id =  strtok(p, ",");
    } else {
        txt = strtok(p, ",");
        id =  strtok(NULL, ",");
    }
    strltrim(id);
    if (pattern == 2) {
        char *s = strtok(NULL, ",");
        strltrim(s);
        strcpy(cln, s);
        sty = strtok(NULL, ",");
    } else {
        strcpy(cln, "\"");
        strcat(cln, cls);
        strcat(cln, "\"");
    }
    strtoupper(cln);
    
    char *px =  strtok(NULL, ",");
    strltrim(px); sscanf(px, "%d", &left);
    px =  strtok(NULL, ",");
    strltrim(px); sscanf(px, "%d", &top);
    px =  strtok(NULL, ",");
    strltrim(px); sscanf(px, "%d", &width);
    px =  strtok(NULL, ",");
    strltrim(px); sscanf(px, "%d", &height);
    
    if (pattern != 2) {
        sty =  strtok(NULL, ",");
    }
    strltrim(sty);
    
    getstyle(wrk3, sty);
    
    char *exsty =  strtok(NULL, "\n");//残り
    if (exsty) {
        strltrim(exsty);
        getstyle(wrk4, exsty);
    } else {
        strcpy(wrk4, "0");
    }
    
    strcpy(cnm, id);
    if (!strncmp(cnm, "IDC_", 4)) {
        strcpy(cnm, id + 4);
        strtolower(cnm);
    }
    int nodec = 0;
    if (!strcmp(cnm, "IDOK")) {
        strcpy(cnm, "btnOK");
    } else if (!strcmp(cnm, "IDCANCEL")) {
        strcpy(cnm, "btnCancel");
    } else if (!strcmp(cnm, "static")) {
        if (m_static == 0) {
            strcpy(cnm, "static_item");
            m_static++;
        } else {
            nodec = 1;
        }
    }
    
    if (!nodec) {
        widgetValueGen(cds, cnm);
    }
    strcat(wrk3, " Or ");
    strcat(wrk3, defstyle);
    
    //コントロールからウィジットへ
    cds->impl += "\n";
    if (!strcmp(cln,"WC_BUTTON") || !strcmp(cln,"\"BUTTON\"")) {
        //トグルのひな形コード
        const char *tggled = "\tIf GTK_TOGGLE_BUTTON(widget)->active Then\n"
                                "\t\t' button is raised.\n"
                             "\tElse\n"
                                "\t\t' button is sunken.\n"
                             "\tEnd If\n";
        //ボタン
        if (strstr(wrk3, "BS_PUSHBUTTON")||strstr(wrk3, "BS_DEFPUSHBUTTON")||
                chknumstyle(wrk3, BS_PUSHBUTTON) || chknumstyle(wrk3, BS_DEFPUSHBUTTON)) {
            
            sprintf(buf, "%s = gtk_button_new_with_label(%s)\n", cnm, txt);
            cds->impl += buf;
            
            //sprintf(buf, "g_signal_connect(G_OBJECT(%s), \"clicked\", G_CALLBACK(@%s_clicked), %s)\n", cnm, cnm, dnm);
            signalgen(cds, cnm, "clicked");
            
            procgen(cnm, "clicked", cds, NULL);
        } else if (strstr(wrk3, "BS_AUTOCHECKBOX")||strstr(wrk3, "BS_CHECKBOX")||
                chknumstyle(wrk3, BS_AUTOCHECKBOX) || chknumstyle(wrk3, BS_CHECKBOX)) {
            
            if (strstr(wrk3, "BS_PUSHLIKE") || chknumstyle(wrk3, BS_PUSHLIKE)) {
                //トグルボタン
                sprintf(buf, "%s = gtk_toggle_button_new_with_label(%s)\n", cnm, txt);
                cds->impl += buf;
                
                //sprintf(buf, "g_signal_connect(G_OBJECT(%s), \"toggled\", G_CALLBACK(@%s_toggled), %s)\n", cnm, cnm, dnm);
                signalgen(cds, cnm, "toggled");
                procgen(cnm, "toggled", cds, tggled);
            } else {
                //チェックボタン
                sprintf(buf, "%s = gtk_check_button_new_with_label(%s)\n", cnm, txt);
                cds->impl += buf;
                
                //sprintf(buf, "g_signal_connect(G_OBJECT(%s), \"toggled\", G_CALLBACK(@%s_toggled), %s)\n", cnm, cnm, dnm);
                signalgen(cds, cnm, "toggled");
                procgen(cnm, "toggled", cds, tggled);
            }
        } else if (strstr(wrk3, "BS_AUTORADIOBUTTON")||strstr(wrk3, "BS_RADIOBUTTON")||
                chknumstyle(wrk3, BS_AUTORADIOBUTTON) || chknumstyle(wrk3, BS_RADIOBUTTON)) {
            //ラジオボタン
            if (strstr(wrk3, "WS_GROUP") || chknumstyle(wrk3, WS_GROUP)) {
                if (m_radios == 0) {
                    cds->decl += "Dim group1 As GSList Ptr\n";
                    m_radios++;
                }
                sprintf(buf, "%s = gtk_radio_button_new_with_label(NULL, %s)\n", cnm, txt);
                cds->impl += buf;
                sprintf(buf, "group1 = gtk_radio_button_group(GTK_RADIO_BUTTON(%s))\n", cnm);
            } else {
                sprintf(buf, "%s = gtk_radio_button_new_with_label(group1, %s)\n", cnm, txt);
            }
            m_radios++;
            cds->impl += buf;
            
            //sprintf(buf, "g_signal_connect(G_OBJECT(%s), \"toggled\", G_CALLBACK(@%s_toggled), %s)\n", cnm, cnm, dnm);
            signalgen(cds, cnm, "toggled");
            procgen(cnm, "toggled", cds, tggled);
        }
        //フォントセット(子ウィジット)
        sprintf(buf,"_child_set_font(%s, font_desc)\n", cnm);
        cds->impl += buf;
    } else if ((!strcmp(cln,"WC_STATIC") || !strcmp(cln,"\"STATIC\"")) && !strstr(wrk3, "RECT") && !strstr(wrk3, "FRAME")) {
        if (strstr(wrk3, "SS_OWNERDRAW") || chknumstyle(wrk3, SS_OWNERDRAW)) {
            sprintf(buf, "%s =  gtk_drawing_area_new ()\n", cnm);
            cds->impl += buf;
        } else if (strstr(wrk3, "SS_BITMAP") || chknumstyle(wrk3, SS_BITMAP)) {
            char *img = (char*)txt;
            if (strstr(img, "IDB_")) {
                img += 4;
                strtolower(img);
            }
            sprintf(buf, "%s = gtk_image_new_from_pixbuf(%s)\n", cnm, img);
            cds->impl += buf;
        } else {
            sprintf(buf, "%s = gtk_label_new(%s)\n", cnm, txt);
            cds->impl += buf;
            //フォントセット(直)
            sprintf(buf,"gtk_widget_modify_font(GTK_WIDGET(%s), font_desc)\n", cnm);
            cds->impl += buf;
        }
    } else if (!strcmp(cln,"WC_EDIT") || !strcmp(cln,"\"EDIT\"")) {
        if (strstr(wrk3, "ES_MULTILINE") || chknumstyle(wrk3, ES_MULTILINE)) {
            sprintf(buf, "%s = gtk_text_view_new()\n", cnm);
        } else {
            sprintf(buf, "%s = gtk_entry_new()\n", cnm);
        }
        cds->impl += buf;
        //フォントセット(子ウィジット)
        sprintf(buf,"_child_set_font(%s, font_desc)\n", cnm);
        cds->impl += buf;
    } else if (!strcmp(cln,"WC_LISTBOX") || !strcmp(cln,"\"LISTBOX\"")) {
        if (m_liststore == 0) {
            cds->decl += "Dim list_store As GtkListStore Ptr\n"
                         "Dim list_column As GtkTreeViewColumn Ptr\n"
                         "Dim list_renderer As GtkCellRenderer Ptr\n";
        }
        //GtkTreeViewをリストボックスっぽく動作させる初期化コード
        cds->impl += "list_store = gtk_list_store_new(1, G_TYPE_STRING)\n";
        sprintf(buf, "%s = gtk_tree_view_new_with_model(GTK_TREE_MODEL(list_store))\n", cnm);
        cds->impl += buf;
        cds->impl += "g_object_unref(list_store)\n";
        sprintf(buf, "gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(%s), FALSE)\n", cnm);
        cds->impl += buf;
        cds->impl += "list_renderer = gtk_cell_renderer_text_new()\n"
                     "gtk_cell_renderer_set_padding(list_renderer, 2, 0)\n"
                     "list_column = gtk_tree_view_column_new_with_attributes(\"Column1\", list_renderer, \"text\", 0, NULL)\n"
                     "gtk_tree_view_append_column(GTK_TREE_VIEW(list1), list_column)\n";
    } else if (!strcmp(cln,"WC_COMBOBOX") || !strcmp(cln,"\"COMBOBOX\"")) {
        if (strstr(wrk3, "CBS_DROPDOWNLIST") || chknumstyle(wrk3, CBS_DROPDOWNLIST)) {
            sprintf(buf, "%s = gtk_combo_box_new_text()\n", cnm);
            cds->impl += buf;
            height = unit->cy + 4;
        } else if (strstr(wrk3, "CBS_DROPDOWN") || chknumstyle(wrk3, CBS_DROPDOWN)) {
            sprintf(buf, "%s = gtk_combo_box_entry_new_text()\n", cnm);
            cds->impl += buf;
            height = unit->cy + 4;
        }
        //フォントセット(直)
        sprintf(buf,"gtk_widget_modify_font(GTK_WIDGET(%s), font_desc)\n", cnm);
        cds->impl += buf;
    } else if (!strcmp(cln,"PROGRESS_CLASS") || !strcmp(cln,"\"MSCTLS_PROGRESS32\"")) {
        //PROGRESS_CLASS    "msctls_progress32"
        sprintf(buf, "%s = gtk_progress_bar_new()\n", cnm);
        cds->impl += buf;
        //フォントセット(直)
        sprintf(buf,"gtk_widget_modify_font(GTK_WIDGET(%s), font_desc)\n", cnm);
       cds->impl += buf;
    }
    sprintf(buf, "gtk_widget_set_size_request(%s, %d, %d)\n", cnm, width * unit->cx / 4, height * unit->cy / 8);
    cds->impl += buf;
    sprintf(buf, "gtk_fixed_put(GTK_FIXED(fixed), %s, %d, %d)\n", cnm, left * unit->cx / 4, top * unit->cy / 8);
    cds->impl += buf;
}
/*
* メニューリソーススクリプト変換処理(再帰してます)
*/

void procmenu(char *p, char *mnm, CodeData *cds, FILE *f, int dep = 0) {
    char mn[64];
    int i = 10, j = 1;
    if (dep > 0) {
        sprintf(mn, "%s%d", mnm, dep);
    } else {
        strcpy(mn, mnm);
    }
    widgetValueGen(cds, mn);
    if (dep == 0) {
        sprintf(buf, "%s = gtk_menu_bar_new()\n", mn);
    } else {
        sprintf(buf, "%s = gtk_menu_new()\n", mn);
    }
    cds->impl += 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, "gtk_container_add(GTK_CONTAINER(%s), gtk_menu_item_new())\n", mn);
                    cds->impl += buf;
                } else if ((p = srchWord(row, "MENUITEM")) != NULL) {
                    p += 9;
                    char *txt = strtok(p, ",");
                    strltrim(txt);
                    char *id = strtok(NULL, ",");
                    strltrim(id);
                    char *mf = strtok(NULL, ",");
                    strltrim(mf);
                    if (!strcmp(mf, "MFT_SEPARATOR")) {
                        sprintf(buf, "gtk_container_add(GTK_CONTAINER(%s), gtk_menu_item_new())\n", mn);
                        cds->impl += buf;
                    } else {
                        if (strstr(id, "IDM_")) {
                            id += 3;
                            *id = 'm';
                            strtolower(id+2);
                        }
                        widgetValueGen(cds, id);
                        sprintf(buf, "%s = gtk_menu_item_new_with_mnemonic(%s)\n", id, txt);
                        cds->impl += buf;
                        sprintf(buf, "gtk_container_add(GTK_CONTAINER(%s), %s)\n", mn, id);
                        cds->impl += buf;
                        //sprintf(buf, "g_signal_connect(G_OBJECT(%s), \"activate\", G_CALLBACK(@%s_activate), NULL)\n", id, id);
                        signalgen(cds, id, "activate");
                        procgen(id, "activate", cds, NULL);
                    }
                } else if ((p = srchWord(row, "POPUP")) != NULL) {
                    p += 5;
                    char *txt = strtok(p, ",");
                    char t[64];
                    strcpy(t,txt);
                    strltrim(t);
                    int k = dep + i;
                    sprintf(buf, "Dim item%d As GtkWidget Ptr\n", k);
                    cds->decl += buf;
                    procmenu(p, mnm, cds, f, dep+i);
                    sprintf(buf, "item%d = gtk_menu_item_new_with_mnemonic(%s)\n", k, t);
                    cds->impl += buf;
                    sprintf(buf, "gtk_container_add(GTK_CONTAINER(%s), item%d)\n", mn, k);
                    cds->impl += buf;
                    sprintf(buf, "gtk_menu_item_set_submenu(GTK_MENU_ITEM(item%d), %s%d)\n", k, mnm, k);
                    cds->impl += buf;
                    i++;
                } else if (srchWord(row, "END") != NULL || strchr(row, '}') != NULL) {
                    break;
                }
            }
        }
    }
}

/*
* メイン関数
* 赴くままにコード書いてるのでリファクタリングが全然不十分。
* ・ダイアログリソースが一つだけ存在するRCでないと正常動作しない
*/

int main(int argc, char *argv[]) {
    char row[256];
    FILE *f = fopen(argv[1], "rt");
    
    SIZE unit = {0,0};
    //int ncw = GetSystemMetrics(SM_CXFRAME) * 2;
    //int nch = GetSystemMetrics(SM_CYFRAME) * 2 + GetSystemMetrics(SM_CYSIZE);
    //int cym = GetSystemMetrics(SM_CYMENU);
    int ncm = 0;
    
    
    CodeData cds;
    
    int dlg = 0;
    char cap[128];
    char fnt[64], did[64], dnm[64], cnm[64], mnm[64];
    char wrk[256],wrk2[160],wrk3[256],wrk4[160];
    int style, exstyle;
    char *p;
    
    if (argc <= 2 ) {
        printf("引数が足りません\n");
        return -2;
    }
    if (!f) {
        printf("ファイルが開けません\n");
        return -1;
    }
    
    
    gtk_init(NULL,NULL);
  
    while (fgets(row, sizeof(row), f)) {
        strchomp(row);
        if (*row == '#') continue;
        if ((p = srchWord(row, "DIALOGEX")) != NULL || (p = srchWord(row, "DIALOG")) != NULL) {
            cds.decl += "' declares for dialog\n";
            cds.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);
                    strltrim(cap);
                } else if ((p = srchWord(row, "FONT")) != NULL) {
                    p = strtok(p+5, ",");
                    sscanf(p, "%d", &fh);
                    p = strtok(NULL, ",");
                    strltrim(p);
                    if (*p == '"') p++;
                    strcpy(fnt, p);
                    p = strchr(fnt,'"');
                    if (p) *p = 0;
                } else if ((p = srchWord(row, "MENU")) != NULL) {
                    p += 4;
                    strltrim(p);
                    strcpy(mnm, p);
                    if (!strncmp(mnm, "IDR_", 4)) {
                        strcpy(mnm, p + 4);
                        strtolower(mnm);
                    }
                    
                    ncm = -1;//メニューあり
                    
                } 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);
                    
                    if (ncm < 0) ncm = unit.cy + 8;
                    
                    strcpy(dnm, did);
                    
                    if (!strncmp(dnm, "IDD_", 4)) {
                        strcpy(dnm, did + 4);
                        strtolower(dnm);
                    }
                    widgetValueGen(&cds, dnm);
                    cds.decl += "Dim vbox As GtkWidget Ptr\n";
                    cds.decl += "Dim fixed As GtkWidget Ptr\n";
                    cds.decl += "Dim font_desc As PangoFontDescription Ptr\n";

                    sprintf(buf,"%s = gtk_window_new(GTK_WINDOW_TOPLEVEL)\n", dnm);
                    cds.impl += buf;
                    if (strstr(str_style,"WS_THICKFRAME") || strstr(str_style,"WS_SIZEBOX") ||
                               chknumstyle(str_style, WS_THICKFRAME)) {
                        sprintf(buf,"gtk_window_set_resizable(GTK_WINDOW(%s), TRUE)\n", dnm);
                    } else {
                        sprintf(buf,"gtk_window_set_resizable(GTK_WINDOW(%s), FALSE)\n", dnm);
                    }
                    cds.impl += buf;
                    sprintf(buf,"gtk_widget_set_size_request(%s, %d, %d)\n", dnm, w * unit.cx / 4, h * unit.cy / 8 + ncm);
                    cds.impl += buf;
                    sprintf(buf,"gtk_widget_set_uposition (%s, %d, %d)\n", dnm, x * unit.cx / 4, y * unit.cy / 8);
                    cds.impl += buf;
                    sprintf(buf,"gtk_window_set_title (GTK_WINDOW(%s), %s)\n", dnm, cap);
                    cds.impl += buf;
                    cds.impl += "vbox = gtk_vbox_new(FALSE,2)\n";
                    if (strcmp(mnm,"NULL")) {
                        sprintf(buf,"gtk_box_pack_start(GTK_BOX(vbox), %s, FALSE, FALSE, 0)\n", mnm);
                        cds.impl += buf;
                    }
                    sprintf(buf,"gtk_container_add(GTK_CONTAINER(%s), vbox)\n", dnm);
                    cds.impl += buf;
                    cds.impl += "fixed = gtk_fixed_new()\n";
                    
                    sprintf(buf,"font_desc = pango_font_description_from_string(\"%s %d\")\n",fnt,fh);
                    cds.impl += buf;
                    cds.impl += "\n'Controls\n";
                    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, &cds);
                        } 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, &cds);
                        } 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, &cds);
                        } 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, &cds);
                        } else if ((p = srchWord(row, "GROUPBOX")) != NULL) {
                            control(1, p + 8, "button",
                                    "BS_GROUPBOX Or WS_CHILD Or WS_VISIBLE",
                                    dnm, &unit, &cds);
                        } else if ((p = srchWord(row, "EDITTEXT")) != NULL) {
                            control(0, p + 8, "edit",
                                    "WS_CHILD Or WS_VISIBLE Or WS_TABSTOP",
                                    dnm, &unit, &cds);
                        } else if ((p = srchWord(row, "LTEXT")) != NULL) {
                            control(1, p + 5, "static",
                                    "WS_CHILD Or WS_VISIBLE",
                                    dnm, &unit, &cds);
                        } else if ((p = srchWord(row, "LISTBOX")) != NULL) {
                            control(0, p + 7, "listbox",
                                    "WS_CHILD Or WS_VISIBLE",
                                    dnm, &unit, &cds);
                        } else if ((p = srchWord(row, "COMBOBOX")) != NULL) {
                            control(0, p + 8, "combobox",
                                    "WS_CHILD Or WS_VISIBLE Or WS_TABSTOP",
                                    dnm, &unit, &cds);
                        } else if ((p = strstr(row, "CONTROL")) != NULL) {
                            control(2, p + 7, "",
                                    "WS_CHILD Or WS_VISIBLE Or WS_TABSTOP",
                                    dnm, &unit, &cds);
                        } else if (strstr(row, "END") != NULL || strchr(row, '}') != NULL) {
                            break;
                        }
                    }
                    cds.impl += "gtk_container_add(GTK_CONTAINER(vbox), fixed)\n";
                    
                    //sprintf(buf,"g_signal_connect(G_OBJECT(%s), \"destroy\", G_CALLBACK(@%s_destroy),NULL)\n", dnm,dnm);
                    signalgen(&cds, dnm, "destroy");
                    procgen(dnm, "destroy", &cds);
                }
            }
        } else if ((p = srchWord(row, "BITMAP")) != NULL) {
            p += 6;
            strltrim(p);
            strreplace(wrk3, p, "\\\\","/");
            char *q = strtok(row, " \t");
            strcpy(cnm, q);
            if (!strncmp(cnm, "IDB_", 4)) {
                strcpy(cnm, q + 4);
                strtolower(cnm);
            }
            sprintf(buf, "Dim Shared %s As GdkPixbuf Ptr\n", cnm);
            cds.decl += buf;
            sprintf(buf, "%s = gdk_pixbuf_new_from_file(%s, NULL)\n", cnm, wrk3);
            cds.impl += buf;
            
        } else if ((p = srchWord(row, "MENU")) != NULL || (p = srchWord(row, "MENUEX")) != NULL) {
            cds.decl += "' declare for menu\n";
            cds.menu += "' menu\n";
            //int n = cds.decl.size() - 1;
            p = strtok(row, " ");
            strcpy(mnm, p);
            if (!strncmp(mnm, "IDR_", 4)) {
                strcpy(mnm, p + 4);
                strtolower(mnm);
            }
            
            procmenu(p+4, mnm, &cds, f, 0);
        }
    }
    fclose(f);
    //printf("'code generated.\n");
    //printf("'template loaded.\n");
    
    getProcCodes(&cds, argv[2]);
    
    //signals と decls と procsを比較して
    //1.declsに一致しないsignalsの削除
    //2.declsに一致するsignalsに
    
    FILE *fout = fopen(argv[2], "wt");
    if (!fout) {
        printf("出力ファイルに書き込めません\n");
        return -1;
    }
    fprintf(fout, "#include \"gtk/gtk.bi\"\n\n");
    fprintf(fout, "declare sub _child_set_font_callback cdecl(widget As GtkWidget Ptr, gdata As gpointer)\n");
    fprintf(fout, "declare sub _child_set_font(widget As GtkWidget Ptr, font_desc As PangoFontDescription Ptr)\n");
    fprintf(fout, "\n");
    map<string,string>::iterator it;
    //Dim As Shared GtkWidget Ptr
    fprintf(fout, "' declare widgets\n");
    for (it = cds.widgets.begin(); it != cds.widgets.end(); it++) {
        fprintf(fout, "%s", it->second.c_str());
    }
    fprintf(fout, "\n");
    fprintf(fout, "%s\n", cds.decl.c_str());
    if (cds.procs.find("initialize") != cds.procs.end()) {
        fprintf(fout, "Declare Sub Initialize()\n");
    }
    
    //fprintf(fout, "%s\n", dclproc.c_str());
    for (it = cds.dclproc.begin(); it != cds.dclproc.end(); it++) {
        fprintf(fout, "%s", it->second.c_str());
    }
    fprintf(fout, "\n");
    fprintf(fout, "gtk_init(NULL,NULL)\n\n");
    fprintf(fout, "%s\n", cds.menu.c_str());
    fprintf(fout, "%s\n", cds.impl.c_str());
    //g_signel_connect
    for (it = cds.signals.begin(); it != cds.signals.end(); it++) {
        fprintf(fout, "%s", it->second.c_str());
    }
    fprintf(fout, "\n");
    fprintf(fout,
        "sub _child_set_font_callback cdecl(widget As GtkWidget Ptr, gdata As gpointer)\n"
        "    gtk_widget_modify_font(GTK_WIDGET(widget), Cast(PangoFontDescription Ptr, gdata))\n"
        "end sub\n\n");
    fprintf(fout,
        "sub _child_set_font(widget As GtkWidget Ptr, font_desc As PangoFontDescription Ptr)\n"
        "    gtk_container_foreach(GTK_CONTAINER(widget), Cast(GtkCallback, @_child_set_font_callback), "
                                "Cast(gpointer, font_desc))\n"
        "end sub\n\n");
    cds.procs["_child_set_font_callback"] = "";
    cds.procs["_child_set_font"] = "";

    if (cds.procs.find("initialize") != cds.procs.end()) {
        fprintf(fout, "Initialize()\n");
    }
    fprintf(fout, "gtk_widget_show_all(%s)\ngtk_main()\n", dnm);

    fprintf(fout, "\n'-------------------------------------------\n\n");
    
    for (it = cds.procs.begin(); it != cds.procs.end(); it++) {
        fprintf(fout, "%s", it->second.c_str());
    }
    fclose(fout);
    //done
}

これで作ったサンプル(wrc2.bas)
#include "gtk/gtk.bi"

declare sub _child_set_font_callback cdecl(widget As GtkWidget Ptr, gdata As gpointer)
declare sub _child_set_font(widget As GtkWidget Ptr, font_desc As PangoFontDescription Ptr)

' declare widgets
Dim Shared btnCancel As GtkWidget Ptr
Dim Shared btnOK As GtkWidget Ptr
Dim Shared dialog1 As GtkWidget Ptr
Dim Shared list1 As GtkWidget Ptr
Dim Shared picture1 As GtkWidget Ptr

' declares for dialog
Dim vbox As GtkWidget Ptr
Dim fixed As GtkWidget Ptr
Dim font_desc As PangoFontDescription Ptr
Dim list_store As GtkListStore Ptr
Dim list_column As GtkTreeViewColumn Ptr
Dim list_renderer As GtkCellRenderer Ptr

Declare Sub Initialize()
Declare Sub btnCancel_clicked Cdecl (ByVal widget As GtkWidget Ptr, gdata As gpointer)
Declare Sub btnOK_clicked Cdecl (ByVal widget As GtkWidget Ptr, gdata As gpointer)
Declare Sub dialog1_destroy Cdecl (ByVal widget As GtkWidget Ptr, gdata As gpointer)
Declare Sub list1_cursor_changed Cdecl (ByVal tv As GtkTreeView Ptr, sdata As gpointer)
Declare Sub picture1_expose_event Cdecl (ByVal widget As GtkWidget Ptr, ByVal evnt As GdkEventExpose, ByVal gdata As gpointer)

gtk_init(NULL,NULL)


' dialog
dialog1 = gtk_window_new(GTK_WINDOW_TOPLEVEL)
gtk_window_set_resizable(GTK_WINDOW(dialog1), FALSE)
gtk_widget_set_size_request(dialog1, 292, 142)
gtk_widget_set_uposition (dialog1, 0, 0)
gtk_window_set_title (GTK_WINDOW(dialog1), "Dialog")
vbox = gtk_vbox_new(FALSE,2)
gtk_container_add(GTK_CONTAINER(dialog1), vbox)
fixed = gtk_fixed_new()
font_desc = pango_font_description_from_string("MS UI Gothic 9")

'Controls

picture1 =  gtk_drawing_area_new ()
gtk_widget_set_size_request(picture1, 106, 66)
gtk_fixed_put(GTK_FIXED(fixed), picture1, 173, 66)

btnCancel = gtk_button_new_with_label("キャンセル")
_child_set_font(btnCancel, font_desc)
gtk_widget_set_size_request(btnCancel, 87, 24)
gtk_fixed_put(GTK_FIXED(fixed), btnCancel, 192, 36)

btnOK = gtk_button_new_with_label("OK")
_child_set_font(btnOK, font_desc)
gtk_widget_set_size_request(btnOK, 87, 24)
gtk_fixed_put(GTK_FIXED(fixed), btnOK, 192, 10)

list_store = gtk_list_store_new(1, G_TYPE_STRING)
list1 = gtk_tree_view_new_with_model(GTK_TREE_MODEL(list_store))
g_object_unref(list_store)
gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(list1), FALSE)
list_renderer = gtk_cell_renderer_text_new()
gtk_cell_renderer_set_padding(list_renderer, 2, 0)
list_column = gtk_tree_view_column_new_with_attributes("Column1", list_renderer, "text", 0, NULL)
gtk_tree_view_append_column(GTK_TREE_VIEW(list1), list_column)
gtk_widget_set_size_request(list1, 154, 121)
gtk_fixed_put(GTK_FIXED(fixed), list1, 12, 10)
gtk_container_add(GTK_CONTAINER(vbox), fixed)

g_signal_connect(G_OBJECT(btnCancel), "clicked", G_CALLBACK(@btnCancel_clicked), NULL)
g_signal_connect(G_OBJECT(btnOK), "clicked", G_CALLBACK(@btnOK_clicked), NULL)
g_signal_connect(G_OBJECT(dialog1), "destroy", G_CALLBACK(@dialog1_destroy), NULL)
g_signal_connect(G_OBJECT(list1), "cursor-changed", G_CALLBACK(@list1_cursor_changed), NULL)
g_signal_connect(G_OBJECT(picture1), "expose-event", G_CALLBACK(@picture1_expose_event), NULL)

sub _child_set_font_callback cdecl(widget As GtkWidget Ptr, gdata As gpointer)
    gtk_widget_modify_font(GTK_WIDGET(widget), Cast(PangoFontDescription Ptr, gdata))
end sub

sub _child_set_font(widget As GtkWidget Ptr, font_desc As PangoFontDescription Ptr)
    gtk_container_foreach(GTK_CONTAINER(widget), Cast(GtkCallback, @_child_set_font_callback), Cast(gpointer, font_desc))
end sub

Initialize()
gtk_widget_show_all(dialog1)
gtk_main()

'-------------------------------------------

Sub btnCancel_clicked Cdecl (ByVal widget As GtkWidget Ptr, ByVal gdata As gpointer)
    'Please write your codes here.
End Sub

Sub btnOK_clicked Cdecl (ByVal widget As GtkWidget Ptr, ByVal gdata As gpointer)
    'Please write your codes here.
End Sub

Sub dialog1_destroy Cdecl (ByVal widget As GtkWidget Ptr, ByVal gdata As gpointer)
    'Please write your codes here.
    gtk_main_quit()
End Sub

Sub Initialize()
    ' リストに行を追加するサンプル
    Dim iter As GtkTreeIter
    Dim store As GtkListStore Ptr
    store = GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(list1)))
    gtk_list_store_clear(store)
    gtk_list_store_append(store, @iter)
    gtk_list_store_set(store, @iter, 0, "みかん", -1)
    gtk_list_store_append(store, @iter)
    gtk_list_store_set(store, @iter, 0, "りんご", -1)
    gtk_list_store_append(store, @iter)
    gtk_list_store_set(store, @iter, 0, "きうぃ", -1)
End Sub

Sub list1_cursor_changed Cdecl (ByVal tv As GtkTreeView Ptr, sdata As gpointer)
    ' リストの選択行から文字列を取得しているサンプル
    Dim As GtkTreeSelection Ptr selection
    Dim As GtkTreeModel Ptr model
    Dim As GtkTreeIter iter
    Dim As gchar Ptr row_string

    '/* get GtkTreeSelection */
    selection = gtk_tree_view_get_selection(tv)
    '/* get selected iter and iter value as a string */
    gtk_tree_selection_get_selected (selection, @model, @iter)
    gtk_tree_model_get (model, @iter, 0, @row_string, -1)

    gtk_button_set_label(GTK_BUTTON(btnCancel), row_string)
    'print *Cast(ZString Ptr, row_string)
End Sub

Sub picture1_expose_event Cdecl (ByVal widget As GtkWidget Ptr, ByVal evnt As GdkEventExpose, ByVal gdata As gpointer)
    ' 描画サンプル
    Dim gc As GdkGC Ptr
    Dim col As GdkColor
    gc = widget->style->fg_gc(GTK_WIDGET_STATE(widget))
    gdk_color_parse("#FF0000", @col)
    gdk_gc_set_rgb_fg_color(gc, @col)
    gdk_draw_rectangle(widget->window, gc, TRUE, 5,5, 45,45)
    gdk_color_parse("#0000FF", @col)
    gdk_gc_set_rgb_fg_color(gc, @col)
    gdk_draw_arc(widget->window, gc, TRUE, 30,20, 45,45,0,360*64)
    gdk_color_parse("#000000", @col)
    gdk_gc_set_rgb_fg_color(gc, @col)
End Sub

gtk-dlg-list.png

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

Comment

2014.10.29 Wed 23:33  ご参考までGTK

2014.10.30 Thu 03:30  Re: ご参考までGTK

コメントありがとうございます。ご提示いただいたページは認識しております。
というよりGTKに手を出すきっかけになりました。
翻訳し、それを公開していただいたことには感謝しております。

FBは日本の利用者が少ないみたいですが、VB全盛時代を職業プログラマとして過ごした私のような世代から見ると「JavaもどきなC#のラッパーであるVB.NET」よりFBの方がずっとVBです。
日本でももっとFBがにぎわうと良いですね。
  • #-
  • 飴屋/菖蒲 
  • [URL]
  • [Edit]






(編集・削除用)

Trackback

http://utau2009.blog114.fc2.com/tb.php/24-60bda2f6

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

Copyright © 飴屋/菖蒲