programing

MessageBox의 GTK 구현

iphone6s 2023. 6. 11. 10:25
반응형

MessageBox의 GTK 구현

Win32의 기능을 구현하기 위해 노력해 왔습니다.MessageBoxGTK를 사용합니다.그 앱은 SDL/OpenGL을 사용하기 때문에 이것은 GTK 앱이 아닙니다.

초기화를 처리합니다(gtk_init) 내부에 있는 것과 같은 것.MessageBox기능은 다음과 같습니다.

int MessageBox(HWND hwnd, const char* text, const char* caption, UINT type)
{
    GtkWidget *window = NULL;
    GtkWidget *dialog = NULL;

    gtk_init(&gtkArgc, &gtkArgv);
    window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
    g_signal_connect(G_OBJECT(window), "delete_event", G_CALLBACK(delete_event), NULL);
    g_signal_connect(G_OBJECT(window), "destroy", G_CALLBACK(destroy), NULL);
    // gcallback calls gtk_main_quit()
    gtk_init_add((GtkFunction)gcallback, NULL);

    if (type & MB_YESNO) {
        dialog = gtk_message_dialog_new(GTK_WINDOW(window), GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_QUESTION, GTK_BUTTONS_YES_NO, text);
    } else {
        dialog = gtk_message_dialog_new(GTK_WINDOW(window), GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_INFO, GTK_BUTTONS_OK, text);
    }

    gtk_window_set_title(GTK_WINDOW(dialog), caption);
    gint result = gtk_dialog_run(GTK_DIALOG(dialog));

    gtk_main();

    gtk_widget_destroy(dialog);

    if (type & MB_YESNO) {
        switch (result) {
        default:
        case GTK_RESPONSE_DELETE_EVENT:
        case GTK_RESPONSE_NO:
            return IDNO;
            break;
        case GTK_RESPONSE_YES:
            return IDYES;
            break;
        }
    }

    return IDOK;
} 

저는 결코 경험이 풍부한 GTK 프로그래머가 아닙니다. 그리고 저는 제가 아마도 끔찍한 잘못을 하고 있다는 것을 깨달았습니다.

그러나 문제는 프로세스가 종료될 때까지 이 기능을 유지하면서 마지막 대화 상자가 나타난다는 것입니다.아이디어 있어요?

음 좋아.다음과 같은 코드를 제안합니다.

typedef struct {
    int type;
    int result;
} DialogData;
    
static gboolean
display_dialog(gpointer user_data)
{
    DialogData *dialog_data = user_data;
    GtkWidget *dialog;
    
    if (dialog_data->type & MB_YESNO)
        dialog = gtk_message_dialog_new(...);
    else
        dialog = gtk_message_dialog_new(...);
    
    // Set title, etc.
    
    dialog_data->result = gtk_dialog_run(...);
    
    gtk_main_quit();  // Quits the main loop run in MessageBox()
    
    return FALSE;
}
    
int MessageBox(...)
{
    DialogData dialog_data;
    
    dialog_data.type = type;
    
    gtk_idle_add(display_dialog, &dialog_data);
    
    gtk_main();
    
    // Do stuff based on dialog_data.result
}

이 구조는 몇 개의 데이터를 전달해야 하기 때문에 필요합니다.gtk_idle_add()call은 메인 루프가 실행 중이고 유휴 상태일 때 실행할 메서드를 추가합니다.FALSE에서 반환되는 가치display_dialog()호출은 한 번만 실행된다는 의미입니다.대화 상자에서 결과를 얻은 후 메인 루프를 종료합니다.그것이 원인이 될 것입니다.gtk_main()당신의는MessageBox()반환하는 방법을 선택하면 거기서 결과에 액세스할 수 있습니다.

GTK+로 대화상자를 관리하려면 창과 주 루프를 직접 관리하는 대신 GtkDialog와 gtk_dialog_run()을 사용합니다.

편집 / 부록:

제 말은 "그냥 사용하세요"라는 것입니다. 저는 당신이 사용하지 않는 창과 쓸모없어 보이는 메인 루프를 왜 만드는지 이해할 수 없습니다. (적어도 당신이 게시한 코드 조각에서).다음과 같은 짧은 글을 쓸 수 있습니다.

int MessageBox(HWND hwnd, const char* text, const char* caption, UINT type)
{
    GtkWidget *dialog ;

    /* Instead of 0, use GTK_DIALOG_MODAL to get a modal dialog box */

    if (type & MB_YESNO)
        dialog = gtk_message_dialog_new(NULL, 0, GTK_MESSAGE_QUESTION, GTK_BUTTONS_YES_NO, text );
    else
        dialog = gtk_message_dialog_new(NULL, 0, GTK_MESSAGE_INFO, GTK_BUTTONS_OK, text );


    gtk_window_set_title(GTK_WINDOW(dialog), caption);
    gint result = gtk_dialog_run(GTK_DIALOG(dialog));
    gtk_widget_destroy( GTK_WIDGET(dialog) );

    if (type & MB_YESNO)
    {
        switch (result)
        {
        default:
        case GTK_RESPONSE_DELETE_EVENT:
        case GTK_RESPONSE_NO:
            return IDNO;
        case GTK_RESPONSE_YES:
            return IDYES;
        }
        return IDOK;
    } 
}

몇 가지 사항:

이름이 지정된 불필요한 최상위 창을 만들고 있습니다(사용하지 않음)window다음 행만 삭제할 수 있습니다.

window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
g_signal_connect(G_OBJECT(window), "delete_event", G_CALLBACK(delete_event), NULL);
g_signal_connect(G_OBJECT(window), "destroy", G_CALLBACK(destroy), NULL);

또한, 흐름이 그다지 맞지 않는 것 같습니다. gtk_main()GTK 메인 루프를 시작합니다. GTK 메인 루프는 무언가가 빠져나올 때까지 차단됩니다. gtk_dialog_run()또한 기본 루프를 시작하지만 단추 중 하나를 클릭하면 바로 종료됩니다.

제 생각에 당신이 그 물건을 제거하는 것으로 충분할 것 같습니다.gtk_init_add()그리고.gtk_main()통화를 하고, 단순히 반환 값을 처리합니다.또한gtk_widget_destroy()gtk_dialog_run()이 반환되면 대화 상자 창이 자동으로 삭제되므로 호출할 필요가 없습니다.

언급URL : https://stackoverflow.com/questions/263/gtk-implementation-of-messagebox

반응형