2008-08-01 14 views
27

का जीटीके कार्यान्वयन मैं जीटीके का उपयोग कर Win32 के MessageBox को लागू करने की कोशिश कर रहा हूं। एसडीएल/ओपनजीएल का उपयोग कर ऐप, इसलिए यह एक जीटीके ऐप नहीं है।संदेशबॉक्स

मैं (gtk_init) MessageBox समारोह के अंदर सामान की तरह initialisation संभाल इस प्रकार है:

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

अब, मैं कर रहा हूँ कोई एक अनुभवी जीटीके प्रोग्रामर भी तरह से, और मुझे लगता है कि मैं शायद कुछ कर रहा हूँ बहुत गलत

हालांकि, मेरी समस्या यह है कि इस फ़ंक्शन के साथ पॉप-अप किया गया अंतिम संवाद प्रक्रिया समाप्त होने तक चारों ओर रहता है। कोई विचार?

उत्तर

17

हम्म, ठीक है। मैं इस तरह के कोड का सुझाव दूंगा, फिर:

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() कॉल मुख्य लूप चल रहा है और निष्क्रिय होने पर चलाने के लिए एक विधि जोड़ता है, और FALSEdisplay_dialog() कॉल से वापसी मान का अर्थ है कि यह केवल एक बार चलाया जाता है। संवाद से परिणाम प्राप्त करने के बाद, हमने मुख्य पाश छोड़ दिया। इससे आपके मुख्य MessageBox() विधि में gtk_main() का कारण बन जाएगा, और आप वहां से परिणाम तक पहुंच पाएंगे।

आशा है कि इससे मदद मिलती है!

6

कुछ बातें:

आप बना रहे हैं (और नहीं उपयोग करते हुए) एक अनावश्यक उच्चस्तरीय खिड़की, 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_dialog_run() भी एक मुख्य पाश शुरू करता है, लेकिन जैसे ही बटनों में से एक क्लिक किया जाता है, यह निकलता है।

मुझे लगता है कि gtk_init_add() और gtk_main() कॉल को निकालने के लिए यह पर्याप्त हो सकता है, और बस वापसी मूल्य से निपटें। gtk_widget_destroy() कॉल अनावश्यक है, क्योंकि gtk_dialog_run() लौटने पर संवाद विंडो स्वचालित रूप से नष्ट हो जाती है।

7

जीटीके + के साथ एक संवाद बॉक्स का प्रबंधन करने के लिए, एक विंडो और मुख्य लूप को प्रबंधित करने के बजाय एक 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; 
    } 
} 
संबंधित मुद्दे