문제

나는 Win32를 구현하려고 노력해 왔습니다. MessageBox GTK를 사용합니다.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() 호출은 메인 루프가 실행 중이거나 유휴 상태일 때 실행될 메서드를 추가하며, FALSE 의 반환 값 display_dialog() call은 한 번만 실행된다는 의미입니다.대화 상자에서 결과를 얻은 후 메인 루프를 종료합니다.그로 인해 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_dialog_run() 또한 메인 루프를 시작하지만 버튼 중 하나를 클릭하자마자 종료됩니다.

제거하면 충분할 것 같아요 gtk_init_add() 그리고 gtk_main() 호출하고 단순히 반환 값을 처리합니다.또한 gtk_widget_destroy() gtk_dialog_run()이 반환되면 대화상자 창이 자동으로 소멸되므로 호출이 필요하지 않습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top