geo1st487 Δημοσ. 26 Αυγούστου 2013 Δημοσ. 26 Αυγούστου 2013 Μπορουμε σε C# να εχουμε κατι οπως την Console.ReadKey() σε WinForms; Μια εντολη δηλαδη που να περιμενει να πατησω ενα πληκτρο για να εκτελεστει οτι υπαρχει απο κατω. Δεν μου χρειαζεται αυτη την στιγμη αλλα ετσι μου ηρθε μια φλασια τωρα και ειπα να το ρωτησω.
παπι Δημοσ. 27 Αυγούστου 2013 Δημοσ. 27 Αυγούστου 2013 Οχι. Σε Winform πας σε event driven που δεν υπαρχει η εννοια του "περιμενε μεχρι", εκει υπαρχει η εννοια του "οταν γινει κατι πες το μου"
geo1st487 Δημοσ. 27 Αυγούστου 2013 Μέλος Δημοσ. 27 Αυγούστου 2013 Οχι. Σε Winform πας σε event driven που δεν υπαρχει η εννοια του "περιμενε μεχρι", εκει υπαρχει η εννοια του "οταν γινει κατι πες το μου" Αν γραψω ενα MessageBox.Show("text"); θα εμφανισει το MessageBox και θα περιμενει μεχρι να το κλεισω. Μονο οταν κλεισει το MessageBox θα εκτελεστουν οι επομενες εντολες. Το ιδιο πραγμα θελω, αλλα να γινεται με πληκτρο οπως με την Console.Readkey. Σκεφτομαι μηπως παιζει κατι σε WinApi.
Directx Δημοσ. 27 Αυγούστου 2013 Δημοσ. 27 Αυγούστου 2013 Αν γραψω ενα MessageBox.Show("text"); θα εμφανισει το MessageBox και θα περιμενει μεχρι να το κλεισω. Μονο οταν κλεισει το MessageBox θα εκτελεστουν οι επομενες εντολες. Το ιδιο πραγμα θελω, αλλα να γινεται με πληκτρο οπως με την Console.Readkey. Σκεφτομαι μηπως παιζει κατι σε WinApi. Αυτό που θέλεις είναι πιθανότατα ένα message-loop το οποίο θα μπλοκάρει για όση ώρα χρειάζεται την ροή του προγράμματος μέχρι ο χρήστης να πατήσει το αναμενόμενο πλήκτρο (MODAL). Αυτό μπορεί να γίνει με την βοήθεια ενός while-loop το οποίο εσωτερικά καλεί την .NET διαδικασία "Application.DoEvent()" (για τους φίλους του C++ Builder/Delphi υπάρχει η Application->ProcessMessages()..) η οποία επιτρέπει στην εφαρμογή μας να διαχειρίζεται τα messages που της στέλνουν τα Windows μένοντας έτσι ζωντανή ενώ ταυτόχρονα η ροή εκτέλεσης του κώδικα της παραμένει στο while-loop μας μέχρι ο χρήστης να πατήσει το αναμενόμενο πλήκτρο (πχ. ESC) ή πχ. να κλείσει την φόρμα κλπ. Φυσικά αυτή η μέθοδος οδηγεί σε αυξημένη χρήση την CPU η οποία μπαίνει σε κατάσταση busy-wait, μια λύση στο πρόβλημα είναι η χρήση της Thread.Sleep ώστε να διακόπτουμε την εκτέλεση του while-loop μας ανά μερικά MS. Προσωπικά πάντως θα προτιμούσα να αποφεύγονται τέτοιες μέθοδοι κατά την σχεδίαση μιας εφαρμογής - σίγουρα μπορεί να βρεθεί ένας καλύτερος τρόπος δράσης που να λαμβάνει υπόψη του την event-driven φύση του Συστήματος.. Ακολουθεί ένα μικρό παράδειγμα γραμμένο σε .NET 3.5/C#: using System; using System.Windows.Forms; namespace winkey { public partial class Form1 : Form { private bool EscPressed, WinClosed; public Form1() { InitializeComponent(); Shown += new EventHandler(Form1_Shown); KeyPress += new KeyPressEventHandler(Form1_KeyPress); FormClosed += new FormClosedEventHandler(Form1_FormClosed); } // Monitor key presses (ESC VK CODE = 0x1B) void Form1_KeyPress(object sender, KeyPressEventArgs e) { EscPressed = e.KeyChar == 0x1b; } // Exiting from Application! void Form1_FormClosed(object sender, FormClosedEventArgs e) { WinClosed = true; } void Form1_Shown(object sender, EventArgs e) { Text = "Press ESC to continue.."; // Busy-waiting for user to press ESC or close this form while (!EscPressed && !WinClosed) { // Process window messages Application.DoEvents(); // Keep busy-wait CPU consumption low System.Threading.Thread.Sleep(100); } if(EscPressed) Text = "Thank you!"; } } }
geo1st487 Δημοσ. 27 Αυγούστου 2013 Μέλος Δημοσ. 27 Αυγούστου 2013 DirectX το ξερω αυτο που λες με While-loop αλλα εχει αυξημενη χρηση CPU. Ειναι μια παλια γνωστη μεθοδος. Το MessageBox παντως σταματαει τη ροη του προγραμματος χωρις να εχει αυξημενη χρηση της CPU.
MitsakosGR Δημοσ. 27 Αυγούστου 2013 Δημοσ. 27 Αυγούστου 2013 Γιατί απλά δεν κάνεις τις ενέργειές σου όταν κάποιος πατήσει το κουμπί;;; Θέλεις να απενεργοποιηθούν όλα τα άλλα buttons, textbox κτλ και να μην γίνει trigger κανένα event μέχρι εκείνη τη στιγμή;
albNik Δημοσ. 27 Αυγούστου 2013 Δημοσ. 27 Αυγούστου 2013 DirectX το ξερω αυτο που λες με While-loop αλλα εχει αυξημενη χρηση CPU. Ειναι μια παλια γνωστη μεθοδος. Το MessageBox παντως σταματαει τη ροη του προγραμματος χωρις να εχει αυξημενη χρηση της CPU. Τα modal dialogs δεν σταματανε την ροη του προγραμματος. Την επικοινωνια του χρηστη (ποντικι-πληκτρολογιο) με το "κατω παραθυρο" διακόπτουν. Τα υπολοιπα events τα ακουει. Δεν ειναι δυσκολο να κανεις τα event που ακουει το modal να περνανε στον owner. Τα winform προγραμματα έχουν STAThread attribute στο οποιο απαγορευεται η Thread.Sleep() στο UI thread.
Directx Δημοσ. 27 Αυγούστου 2013 Δημοσ. 27 Αυγούστου 2013 (επεξεργασμένο) [..]Το MessageBox παντως σταματαει τη ροη του προγραμματος χωρις να εχει αυξημενη χρηση της CPU.[..]Για ρίξε μια ματιά εδώ (UI-Modality) και εδώ (*Code-Modality). * Σύμφωνα με τον Chen υπάρχει ένα παράδειγμα στο MSDN για Code-Modality (βασίζεται στις συναρτήσεις PeekMessage και MsgWaitForMultipleObjects) αλλά αυτή την στιγμή δεν ανοίγει ή δεν είναι πλέον διαθέσιμο :-/ --EDIT/UPDATE: Εδώ μπορείς να βρεις μια custom υλοποίηση του MessageBox μαζί με το απαραίτητο message-loop για code-modality (σε WinAPI). ..και μια προσαρμογή της προηγούμενης ανάρτησης στην *WaitMessage() η οποία διακόπτει την εκτέλεση του Thread όταν δεν υπάρχουν μηνύματα (οπότε κρατά την χρήση της CPU σε χαμηλό επίπεδο): * Η DoEvents() φαίνεται ότι εκτελεί τις απαραίτητες συναρτήσεις διαχείρισης μηνυμάτων κατά τέτοιο τρόπο που μπορούμε να χρησιμοποιήσουμε ύστερα την WaitMessage() άμεσα. using System;using System.Windows.Forms; using System.Runtime.InteropServices; namespace winkey { public partial class Form1 : Form { [DllImport("user32.dll")] static extern bool WaitMessage(); private bool EscPressed, WinClosed; public Form1() { InitializeComponent(); Shown += new EventHandler(Form1_Shown); KeyPress += new KeyPressEventHandler(Form1_KeyPress); FormClosed += new FormClosedEventHandler(Form1_FormClosed); } // Monitor key presses (ESC VK CODE = 0x1B) void Form1_KeyPress(object sender, KeyPressEventArgs e) { EscPressed = e.KeyChar == 0x1b; } // Exiting from Application! void Form1_FormClosed(object sender, FormClosedEventArgs e) { WinClosed = true; } void Form1_Shown(object sender, EventArgs e) { Text = "Press ESC to continue.."; // Busy-waiting for user to press ESC or close this form while (!EscPressed && !WinClosed) { // Process window messages Application.DoEvents(); // Suspend current thread until a new message arrives WaitMessage(); } if (EscPressed) Text = "Thank you!"; } } } Καλή συνέχεια! Επεξ/σία 28 Αυγούστου 2013 από Directx
albNik Δημοσ. 28 Αυγούστου 2013 Δημοσ. 28 Αυγούστου 2013 Directx σταματα να βαζεις αυτη τη λουπα με DoEvents, δεν γινεται καλυτερη με Wait (ουτε Sleep ή Join). Δες τους κινδύνους της. http://stackoverflow.com/questions/5181777/use-of-application-doevents Επίσης http://stackoverflow.com/questions/4154429/apartmentstate-for-dummies Requirements are that you never block the thread for any amount of time and that you pump a message loop. The latter requirement is met by a WPF or Winforms' UI thread but you will need to take care of it yourself if you create your own STA thread. The common diagnostic for breaking the contract is deadlock
Retromaniac Δημοσ. 28 Αυγούστου 2013 Δημοσ. 28 Αυγούστου 2013 Δεν μπορώ πραγματικά να καταλάβω που χρειάζεται αυτό σε event driven programming. Μπορείς να μας δώσεις ένα παράδειγμα για το πως θα σε βοηθούσε;
Directx Δημοσ. 28 Αυγούστου 2013 Δημοσ. 28 Αυγούστου 2013 Directx σταματα να βαζεις αυτη τη λουπα με DoEvents, δεν γινεται καλυτερη με Wait (ουτε Sleep ή Join). Δες τους κινδύνους της. http://stackoverflow.com/questions/5181777/use-of-application-doevents Επίσης [/size] http://stackoverflow.com/questions/4154429/apartmentstate-for-dummies Requirements are that you [/size]never block the thread for any amount of time and that you pump a message loop. The latter requirement is met by a WPF or Winforms' UI thread but you will need to take care of it yourself if you create your own STA thread. The common diagnostic for breaking the contract is deadlock[/size] Κοίταξε όταν ο φίλος μας ζητάει κάποια ιδιόρρυθμα πράγματα, καταλήγουμε αυτόματα σε κάποιες ιδιόρρυθμες λύσεις. Την (παρα)φιλολογία γύρο από την DoEvent την γνωρίζω καθώς λόγο VCL είχαμε χρόνια την ανάλογη διαδικασία Application->ProcessMessages(). Αν λοιπόν γνωρίζεις τι κάνει η εν λόγο εντολή και λάβεις τα μέτρα σου μπορεί να φανεί χρήσιμη αν όχι πρόβλημα σου, αν απλά την απορρίψεις συλλήβδην κανένα πρόβλημα, προβλήματα που λύνονται εύκολα θα τα λύσεις λιγότερο εύκολα, από εμένα no prob και φυσικά μην περιμένεις να γίνω απολογητής της DoEvent
geo1st487 Δημοσ. 28 Αυγούστου 2013 Μέλος Δημοσ. 28 Αυγούστου 2013 Θέλεις να απενεργοποιηθούν όλα τα άλλα buttons, textbox κτλ και να μην γίνει trigger κανένα event μέχρι εκείνη τη στιγμή; Οχι. Ολα τα controls θελω να ειναι ενεργοποιημενα και να δουλευουν τα events κανονικα απλα να περιμενει ενα πληκρο για να προχωρησει παρακατω. Δεν μπορώ πραγματικά να καταλάβω που χρειάζεται αυτό σε event driven programming. Μπορείς να μας δώσεις ένα παράδειγμα για το πως θα σε βοηθούσε; Μεχρι στιγμης δεν μου χρειαστηκε ποτε απλα μου ηρθε μια φλασια και ειπα να το ρωτησω γιατι δεν βρηκα κατι αντιστοιχο με την Console.ReadKey(). Αυτο που ρωταω μου θυμιζει το εξης γνωστο μηνυμα: "Press any key to continue..." Σιγουρα υπαρχουν εναλλακτικοι τροποι αλλα λεω μηπως ενα readkey θα ηταν ενας ευκολοτερος και πιο απλοϊκος τροπος.
albNik Δημοσ. 28 Αυγούστου 2013 Δημοσ. 28 Αυγούστου 2013 Οχι. Ολα τα controls θελω να ειναι ενεργοποιημενα και να δουλευουν τα events κανονικα απλα να περιμενει ενα πληκρο για να προχωρησει παρακατω. Μην πετας dialogs ή εμφανιζε non-modal dialogs (TopMost για να μην κρυβονται πίσω απο το κυριο). Το MessageBox ειναι παντα modal.
Retromaniac Δημοσ. 28 Αυγούστου 2013 Δημοσ. 28 Αυγούστου 2013 Οχι. Ολα τα controls θελω να ειναι ενεργοποιημενα και να δουλευουν τα events κανονικα απλα να περιμενει ενα πληκρο για να προχωρησει παρακατω. Μεχρι στιγμης δεν μου χρειαστηκε ποτε απλα μου ηρθε μια φλασια και ειπα να το ρωτησω γιατι δεν βρηκα κατι αντιστοιχο με την Console.ReadKey(). Αυτο που ρωταω μου θυμιζει το εξης γνωστο μηνυμα: "Press any key to continue..." Σιγουρα υπαρχουν εναλλακτικοι τροποι αλλα λεω μηπως ενα readkey θα ηταν ενας ευκολοτερος και πιο απλοϊκος τροπος. Μήπως να το ψάξεις τότε; Γιατί το πιθανότερο είναι ότι δεν θα το χρειαστείς ΠΟΤΕ. Οπότε μόνο για "ακαδημαικούς" λόγους.... 1
παπι Δημοσ. 28 Αυγούστου 2013 Δημοσ. 28 Αυγούστου 2013 Οχι. Ολα τα controls θελω να ειναι ενεργοποιημενα και να δουλευουν τα events κανονικα απλα να περιμενει ενα πληκρο για να προχωρησει παρακατω. ` Να παει που "παρακατω";
Προτεινόμενες αναρτήσεις
Δημιουργήστε ένα λογαριασμό ή συνδεθείτε για να σχολιάσετε
Πρέπει να είστε μέλος για να αφήσετε σχόλιο
Δημιουργία λογαριασμού
Εγγραφείτε με νέο λογαριασμό στην κοινότητα μας. Είναι πανεύκολο!
Δημιουργία νέου λογαριασμούΣύνδεση
Έχετε ήδη λογαριασμό; Συνδεθείτε εδώ.
Συνδεθείτε τώρα