飴屋ぷろじぇくと

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

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

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

2014.10.30[木] WindowsリソースからFreeBASIC+GTK(その3)


UTAUを作った動機を知れば自ずと判ることなんですが、飴屋はこんな風に手間かけて手間を減らすツールを作るのが好きなんです。

というわけで、今回は画像関係の話題。

gtk-app-dlg.png

こんな画面をサンプルに載せましたが、このイメージ、実は問題がありまして、これって、実行時に画像を読み込んでいるんです。具体的にはGdkPixbufに読み込んでいます。
bitmap1 = gdk_pixbuf_new_from_file("./apple.bmp", NULL)
これを以下のようにしてGtkImageにして表示してます。
image1 = gtk_image_new_from_pixbuf(butmap1)
まあこれはこれで良いんですが、実行時に結合となると後々厄介かもしれないので本来のリソースのように実行ファイルに埋め込めないものかとやってみました。

まずソースにバイナリデータを記述するのですが、FreeBasicではこんな表記が出来るようです。
Dim pixdata As String = !"\212\234\127\128\129\065\066"
そしてデータはやたら長いので行継続記号"_"を使って、
Dim pixdata As String = _
!"\212\234\127\128\129\065\066\128\129\065\066\128\129\065\066" _
!"\234\127\128\129\065\212\173\129\065\128\066\128\129\154\170" _
!"\252\234\227\128\129\065\226\065\128\129\066\066\128\129\165"
こんな風に書きます。
変換プログラム内で画像ファイルをこのようなソースに変換するわけですが、折角なのでこちらでの画像の読み込みもGTKを使用しました。実装はこんな関数。
/*
 * 画像リソースをソースコードに変換する
 */

void pixToText(CodeData *cds, const char *filename, const char *pname) {
    string text;
    char fname[256];
    strcpy(fname, filename);
    fname[0] = ' ';
    char *p = strchr(fname, '"');
    if (p) *p = 0;
    strltrim(fname);
    GdkPixbuf *pixbuf = gdk_pixbuf_new_from_file(fname, NULL);
    int n_channels = gdk_pixbuf_get_n_channels(pixbuf);
    gboolean has_alpha = gdk_pixbuf_get_has_alpha(pixbuf);
    guchar *pix = gdk_pixbuf_get_pixels(pixbuf);
    int rowstride = gdk_pixbuf_get_rowstride(pixbuf);
    int bpsamp = gdk_pixbuf_get_bits_per_sample(pixbuf);
    int w = gdk_pixbuf_get_width(pixbuf);
    int h = gdk_pixbuf_get_height(pixbuf);
    int len = rowstride * h;
    sprintf(buf, "Const %s_n_channels As Integer = %d\n", pname, n_channels);
    text += buf;
    sprintf(buf, "Const %s_has_alpha As Integer = %d\n", pname, has_alpha);
    text += buf;
    sprintf(buf, "Const %s_bits_per_sample As Integer = %d\n", pname, bpsamp);
    text += buf;
    sprintf(buf, "Const %s_width As Integer = %d\n", pname, w);
    text += buf;
    sprintf(buf, "Const %s_height As Integer = %d\n", pname, h);
    text += buf;
    sprintf(buf, "Const %s_rowstride As Integer = %d\n", pname, rowstride);
    text += buf;
    sprintf(buf, "Const %s_pixcels As String = _\n!\"", pname);
    text += buf;
    for (int i = 0; i < len; i++) {
        sprintf(buf, "\\%03u", pix[i]);
        if (i > 0 && i % 25 == 0) {
            text += "\" _\n!\"";
        }
        text += buf;
    }
    text += "\"\n";
    
    sprintf(buf, "%s.bi", pname);
    FILE *fb = fopen(buf, "wt");
    fprintf(fb, "%s", text.c_str());
    fclose(fb);

    sprintf(buf, "#include \"%s.bi\"\n", pname);
    cds->incs += buf;
}

ソースに埋め込むコードは画像のバイナリデータをAscii表現しているので無駄に長くなります。なので出力ファイルを分割して画像のコードはインクルードファイルに格納しています。もちろん #include は自動で挿入されます。
生成した bas ファイル
#include "gtk/gtk.bi"

#include "bitmap1.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 image1 As GtkWidget Ptr

Dim Shared bitmap1 As GdkPixbuf Ptr
' declares for dialog
Dim vbox As GtkWidget Ptr
Dim fixed As GtkWidget Ptr
Dim font_desc As PangoFontDescription 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)

gtk_init(NULL,NULL)


bitmap1 = gdk_pixbuf_new_from_data(Cast(gchar Ptr, @bitmap1_pixcels), GDK_COLORSPACE_RGB,bitmap1_has_alpha, bitmap1_bits_per_sample,bitmap1_width,bitmap1_height,bitmap1_rowstride,NULL,NULL)
' dialog
dialog1 = gtk_window_new(GTK_WINDOW_TOPLEVEL)
gtk_window_set_resizable(GTK_WINDOW(dialog1), FALSE)
gtk_widget_set_size_request(dialog1, 279, 130)
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 8")

'Controls

image1 = gtk_image_new_from_pixbuf(bitmap1)
gtk_widget_set_size_request(image1, 100, 100)
gtk_fixed_put(GTK_FIXED(fixed), image1, 34, 13)

btnCancel = gtk_button_new_with_label("キャンセル")
_child_set_font(btnCancel, font_desc)
gtk_widget_set_size_request(btnCancel, 75, 23)
gtk_fixed_put(GTK_FIXED(fixed), btnCancel, 193, 34)

btnOK = gtk_button_new_with_label("APPLE")
_child_set_font(btnOK, font_desc)
gtk_widget_set_size_request(btnOK, 75, 23)
gtk_fixed_put(GTK_FIXED(fixed), btnOK, 193, 9)
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)

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()
    
End Sub

bitmap1.bi は長いので一部分だけ
Const bitmap1_n_channels As Integer = 3
Const bitmap1_has_alpha As Integer = 0
Const bitmap1_bits_per_sample As Integer = 8
Const bitmap1_width As Integer = 100
Const bitmap1_height As Integer = 100
Const bitmap1_rowstride As Integer = 300
Const bitmap1_pixcels As String = _
!"\240\241\243\240\241\243\240\241\243\240\241\243\241\242\244\241\242\244\241\242\244\242\243\245\242" _
(以下略)

変換プログラムのソース
/*

コンパイル:

[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 -lgdk_pixbuf-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 gdk_pixbuf-2.0.lib cairo.lib


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

 rc2fbgtk test.rc output.bas

 fbc output.bas -p %GTK%\lib

 output.exe

ライセンス:
  自己責任にて、自由に使用してもらって構いません。

  (いずれLGPLかそれに類するライセンスにするかもしれませんが、
   まだそんな大層なものではないので)

著作者:
  (C)2014  飴屋プロジェクト・飴屋/菖蒲

*/


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

#include <gtk/gtk.h>
#include <gdk/gdk.h>
#include <gdk-pixbuf/gdk-pixbuf.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 incs; //インクルード
    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;
            
            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;
                
                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;
                
                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;
            
            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;
                        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;
                }
            }
        }
    }
}
/*
 * 画像リソースをソースコードに変換する
 */

void pixToText(CodeData *cds, const char *filename, const char *pname) {
    string text;
    char fname[256];
    strcpy(fname, filename);
    fname[0] = ' ';
    char *p = strchr(fname, '"');
    if (p) *p = 0;
    strltrim(fname);
    GdkPixbuf *pixbuf = gdk_pixbuf_new_from_file(fname, NULL);
    int n_channels = gdk_pixbuf_get_n_channels(pixbuf);
    gboolean has_alpha = gdk_pixbuf_get_has_alpha(pixbuf);
    guchar *pix = gdk_pixbuf_get_pixels(pixbuf);
    int rowstride = gdk_pixbuf_get_rowstride(pixbuf);
    int bpsamp = gdk_pixbuf_get_bits_per_sample(pixbuf);
    int w = gdk_pixbuf_get_width(pixbuf);
    int h = gdk_pixbuf_get_height(pixbuf);
    int len = rowstride * h;
    sprintf(buf, "Const %s_n_channels As Integer = %d\n", pname, n_channels);
    text += buf;
    sprintf(buf, "Const %s_has_alpha As Integer = %d\n", pname, has_alpha);
    text += buf;
    sprintf(buf, "Const %s_bits_per_sample As Integer = %d\n", pname, bpsamp);
    text += buf;
    sprintf(buf, "Const %s_width As Integer = %d\n", pname, w);
    text += buf;
    sprintf(buf, "Const %s_height As Integer = %d\n", pname, h);
    text += buf;
    sprintf(buf, "Const %s_rowstride As Integer = %d\n", pname, rowstride);
    text += buf;
    sprintf(buf, "Const %s_pixcels As String = _\n!\"", pname);
    text += buf;
    for (int i = 0; i < len; i++) {
        sprintf(buf, "\\%03u", pix[i]);
        if (i > 0 && i % 25 == 0) {
            text += "\" _\n!\"";
        }
        text += buf;
    }
    text += "\"\n";
    
    sprintf(buf, "%s.bi", pname);
    FILE *fb = fopen(buf, "wt");
    fprintf(fb, "%s", text.c_str());
    fclose(fb);

    sprintf(buf, "#include \"%s.bi\"\n", pname);
    cds->incs += buf;
}

/*
 * メイン関数
 * 赴くままにコード書いてるのでリファクタリングが全然不十分。
 * ・ダイアログリソースが一つだけ存在する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";
                    
                    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);
            sprintf(buf, "%s = gdk_pixbuf_new_from_data(Cast(gchar Ptr, @%s_pixcels), GDK_COLORSPACE_RGB,"
                                                        "%s_has_alpha, %s_bits_per_sample,"
                                                        "%s_width,%s_height,%s_rowstride,NULL,NULL)\n"
                                                        ,cnm, cnm, cnm, cnm, cnm, cnm, cnm);
            cds.impl += buf;
            pixToText(&cds, wrk3, cnm);
        } 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");
    fprintf(fout, "\n%s\n", cds.incs.c_str());
    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
}

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

Comment






(編集・削除用)

Trackback

http://utau2009.blog114.fc2.com/tb.php/25-f801d077

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

Copyright © 飴屋/菖蒲

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