Hrm, sollte eigentlich mit ^% stimmen.
Du kannst das auch so lösen:
void ^ Int32 ColumnFetch (IntPtr hQs, String ^name, String ^val, UInt32 vSize,
bool fill)
{
cli::pin_ptr<const System::Char> pChar = PtrToStringChars( pString);
}
Mit folgenden Export:
Codeproject den managed String Converter benutzen:
Mit folgenden Import in C#:
[DllImport ("<deine>.dll", CharSet = CharSet.Auto)]
public static extern int call (IntPtr hQs, string name, string val, int vSize, bool fill);
Für den DLL Exmport für C# machst folgendes in deinen C++ /cli Code Beispiel:
__declspec(dllexport) Int32 DoColumnFetch(IntPtr hQs, String ^name, String ^val, UInt32 vSize,
bool fill)
Oder bei dir wegen std wie folgt exportieren.
extern "C" __declspec(dllexport) void __stdcall Int32 ColumnFetch(IntPtr hQs, String ^name, char ^%val, UInt32 vSize,
bool fill)
{
ColumnFetch (usw..);
}
Für den import in C# dann wie folgt:
[DllImport ("<deine>.dll", CharSet = CharSet.Auto)]
public static extern int call (IntPtr hQs, string name, char val, int vSize, bool fill);
/ps
Hoffe hat sich kein Fehler eingeschlichen, habs nur so runtergetippselt .. ich weis warum ich C++ nicht mag.. dauernd vertippt 😉
Hrm, glaube so direkt kann man das nicht sagen. Versuch xxxprod Lösungsvorschlag mal aus.
Sollte das nicht hinhauen, die Hammermethode wäre alle Windowsnachrichten der Controls zu unterbinden bis auf WM_DESTROY. Dies müsstest du allerdings über Subclassing realisieren - nur ob das wirklich alles so eine gute Idee ist.
Was stört den genau an den Events?
Hrm, das (nicht gebundenes) hatte ich überlesen. Na ja, das was bereits verwendest wäre die einfachste Lösung, spricht auch nichts dagegen.
Du kannst auch DataTable.WriteXML benutzen um das Schema auszulesen und DataTable.ReadXML um nur das Schema wieder einzulesen, wäre etwas schöner.
Du kannst das übers Schema lösen.
Hier nen Beispiel für ne OleDB weis ja nicht was verwendest 🙂
using (OleDbConnection oleDbConnection = new OleDbConnection(this.Connection))
{
oleDbConnection.Open();
DataTable dtTables = oleDbConnection.GetOleDbSchemaTable(OleDbSchemaGuid.Columns, new object[] { null, null, "Kunde", null });
}
Wenn in google suchst findest noch andere Schematas die du evtl brauchen könntest, aber denke vorweg interessierne dich die Columns.
Hatte nen Tipfehler drinnen, bei der zweiten Lösung: Dort kannst über WM_CREATE nicht über SetWindowex den Button lokalisieren sondern über lParam. Hatte nur grade was mit SetWinowEx gearbeitet.. irgendwie Freudscher versprecher 🙂
Habs im Post korrigiert.
Hallo Peter,
[Erste Lösung, die einfachste]
nutze **FindWindowEx **und du kannst auch die Childfenster (Controls) Handels ausfindig machen.
Für das Wegklicken schicke WM_CLICK= 0x00F5 an den Button "Yes" selbst. mit PostMessage (nicht SendMessage). Über den C++ code unten kannst auch nach den Buttonnamen dann suchen.
[Zweite Lösung, die schönere und wiederverwendbare]
Du könntest auch Subclassing verwenden, siehe hierzu dr4g0n76 Artikel, der machts dir schon recht einfach, mit System.Windows.Forms.NativeWindow AssignHandle(hWnd) kannst das SubClassing vereinfachen. Dann kannst sogar mit WM_CREATE über lParam die jeweiligen Childbuttons lokalisieren und über ihren Text Identifizieren (wie in der ersten Lösung).
C++ (ist ja fix in C# umgesetzt)
td::string GetWindowText( HWND wnd )
{
std::string text;
WPARAM length = SendMessage( wnd, WM_GETTEXTLENGTH, 0,
0, 0 );
if( length > 0 )
{
char *buffy = new char [length+1];
LRESULT got = SendMessage( wnd, WM_GETTEXT,
TTEXT, length+1, (LPARAM)buffy );
if( (LRESULT)length == got )
text = buffy;
delete [] buffy;
}
return text;
}
Jetzt wüsstest du die Buttons (suchst halt nach English udn Deutscher Sprachausgabe) und setzt evtl. von aussen welcher MessageBox Button weggeklickt werden soll. Somit hast dein eigenes Tool dafür geschrieben .-)
Hrm, und wenn man versucht das mit einen Webbrowserplugin zu koppeln der die Bilder eben naja (leider) temporär im Speicher hällt, oder vielleicht sogar in dessen eigenen Resource und nach beendigung des Browsers wiederum den Speicher / Resource leert.
Natürlich wirds dann schon ziemlich Aufwendig und auch bis die Seite sich aufbaut dauerst dann evtl. seine Zeit. Einen Tod wird man sterben müssen.
Hrm, kann man nicht versuchen anhand von Regex die Tags auszulesen?
<img src="<AAEAAAD....>" alt="Tanzmaus">
Und eben <Source.png> den darin enthaltenen string umzustellen (wie BSP von mir) und im Anschluss das Bild in einen passenden Ordner reinspeichern (wenn Server, dann halt Serverpfad). Und den Pfadnamen hinterlegt wie eine eindeutige Nummer oder irgend ein zusammengebauter Namen wie das typische .\Sourcefolder\Bild1.jpg als Source verwendet? - Klar kostet halt Zeit und performance aber wäre denke ich ein Weg.
Das kompilieren ist ja kein Ding, solltest dir nur ein gutes Designpattern überlegen für die Anwendung des Bnutzers zum erstellen der DLL's. Und ebenso umgekehrt wenn diese wieder einließt.
Für beides passt Command Pattern ganz gut, nutze dazu die Observer Patterns und du hast eine leichteres Fehelrhandling.
Denk dran, da bei command patterns eh schon Kompositionen bildest das diese auch nunmehr über eine gemeinsamme Singletonklasse steuerst. So erreicht eine unabhängige Kommunikationsschicht zwischen dne Plugins.
Ergo, durchs Observerpattern bekämst bei einen beschädigten Plugin den Fehler mit den das Plugin erzeugt , durch die gemeinsamme Singletonklasse mit die als Komunikationsschicht dient (daher 1 delegate über das alle Anfragen wie Senden und Empfangen durchjagst) erhällst du die Möglichkeit den Fehler erst gar nicht ausführbar zu machen. Das einzige was dir noch Fehlt ist, ein Pluginloader, hier bietet sich eine ganz normale Shcnittstelle an, z.b. ein Interface - Laden kannst du die Plugins via Activator.CreateInstance aus derAssembly heraus.
Kostet zwar alles seine Zeit aber wird dadurch leichter.
Hrm, du brauchst dafür eine Verfügbarkeitsprüfung um deine dynamsich gehaltenen Listen zu füllen.
Dann gehst du von den größten Verfügbaren Betrag aus, wenn größter Verfügbarer Betrag z.b. dein 5 Euroscheine nicht vorhanden oder Komuliert größer als gewünschter Betrag gehe zur nächsten Liste. Wiederhole das solange bis Betrag erfüllt ist.
Diese Art der Verfügbarkeitsprüfung würde somit immer versuchen anhand deiner größt verfügbaren Geldmittel so wenig wie möglich Kleingeld auszuspuken.
Weis nicht, grade bei größeren Programmen finde ich ein Programmablaufdiagramm schlüssiger. Eigentlich sehe ich es so das nicht der Programmierer den Ablauf eines Programms vorgibt und somit eh kein UML vorgeben kann. Sondern das die Aufgabe vom Produktleiter ist, dieser erstellt den Programmablaufplan und der Systemarchitekt gibt vor wie z.B. das UML aussieht.
Der Programmierer geht nicht anhand des UML's vor, ihn interessiert das große ganze ja nicht - sondern kümmert sich nur darum das sein Modul vom Programmablaufplan her das erfüllt was es soll - das UML kann man dann nur verwenden wenn der Systemarchitekt selbst nicht die Schnittstellen programmiert.
Aber ich denke das hängt halt von der Struktur der Firma ab, wenn der Programmierer die Aufgaben von Systemarchitekt und (oder) Produktleiter übernimmt dann machen UML's schon ihren Sinn. Damit man das große ganze nicht aus den Augen verliert - aber eigentlich sollte das immer getrennt sein wie ich finde.
Du könntest alternativ dazu einfach ein Event nach aussen geben und von aussen das Bild setzen. Über den sender bei nen Standardevent wie z.b. das Klickereigniss deines dynamischen ToolbarButton gibst diesen eben als sender mit. Dein ToolbarButton sollte dann eben die Eigenschaft Image mitliefern. So kannst du von aussen das Bild setzen ohne das dein UserControl Bilder überhaupt fest integriert reinlädt. Würde dir soweiso empfehlen deine dynamsichen objekte wie das ToolBarButton Item über den Designer von aussen zu konfigurieren. Somit hast du keine Resourcen wie Bilder / Texte usw. in dem UserControl selbst 🙂
Hrm, veränderst du evtl. beim Sizen größen oder werden die Controls irgendwo im Code von der Ausrichtung beeinflusst ?
Ups.. daran hatte ich nicht gedacht.
Hallo armin6004,
mit folgenden Beispiel kannst du z.b. ein Bild über einen BinaryFormatter herstellen.
Vermute stark das nach deiner Verschlüsselung dieser in Binärer Form vorliegt. Wenn nicht, ändert sich ja nur der Einlesevorgang vom Stream. Das Beispiel zeigt daher eine Möglichkeit von vielen auf.
string icon = "AAEAAAD/////AQAAAAAAAAAMAgA..." // wäre in wirklichkeit sehr lange
private Icon DeserializeIconFromBase64Text(string text)
{
Icon img = null;
byte[] memBytes = Convert.FromBase64String(text);
IFormatter formatter = new BinaryFormatter();
MemoryStream stream = new MemoryStream(memBytes);
img = (Icon)formatter.Deserialize(stream);
stream.Close();
return img;
}
Du kannst vor "Convert.FromBase64String" natürlich ganz normal deinen entschlüsselungsalgorithmus reinbauen 🙂
Na ja kritzel derzeit immer noch im GDI herum 😮)
Hallo the-cook,
leider fehlen uns Angaben über dein exaktes Problem.
Siehe heirzu bitte: Wie poste ich richtig?
Also, in deinen Fall wäre nicht schlecht zu wissen was du mit den Controls machst, sie z.B. dynamsich andordnest, irgendwo bei einen bestimmten Fall Visible = false aufrufst oder das Docking vielleicht nicht stimmt oder ob die Controls selbst erstellt wurden und vielelicht flimmern usw.
Also einfach etwas mehr Info bitte - kannst auch nen Bild anfügen 🙂
ich glaube JAck30lena hatte dir zwar genau das mitteilen wollen, runzelt aber bestimmt nun mit der Stirn .-)
Du brauchst ja nicht die Pfade ändern sondern nur auf den entsprechenden Trigger zu reagieren.
Wenn Fall A :
item.Image = global::myControls.Properties.Resources.rot
Wenn Fall B
item.Image = global::myControls.Properties.Resources.blau
Die Fälle könnten z.B. über ein Event getriggert werden, wie z.B. ein Click Event.
Wenn es dir jetzt um eine Designerkomponente geht die zur Designerlaufzeit geladen und entladen wird mit dynamsichen Resourcen, dann wäre dein zweiter Ansatz der richtige - aber glaube kaum dass das gemeint hattest.
Hrm, wenn es etwas kosten darf DevExpress liefert viele solcher Controls mit 🙂
Hrm, die Vorposter haben zwar allesammt recht - nur wenn ich Sin und Cos schon sehe denke ich mal möchtest schon exakte Ergebnisse erzielen und diese auch irgendwann mal Grafisch exakt darstellen. Nutze lieber PointF und für die Grafische Darstellung ebenso den floating Wert.
Wenn es alerdings egal sein sollte ob das Ding richtig dargestellt wird oder nicht, vergiss das posting 😉
Hrm, muss zugeben habe weder Struktogramme noch UML's jemals benutzt noch den Sinn dahinter erkannt. Selbst bei Teamarbeiten bietet jeder für seine Module die passenden Schnittstellen an. Gut, kann sein das bei größeren Teamprojekten es natürlich Sinn macht die Schnittstellen via UML den anderen darzulegen.
Aber mal ehrlich, nen paar XML Kommentare die man sich durchlesen kann helfen einen schneller weiter durchzusteigen als ein UML. Ich denke es ist gut wenn man UML's lesen oder diese nachträglich durch den VS Support dafür ausdrucken und sich an die Wand pinnen kann. Aber eigentlich haben UML's mir in der Vergangenheit nur geholfen indem ich meinen Produktleiter damit leichter die einzelnen Module als ganzes aufzeigen konnte.
Ansonsten fällt mir kein Gebrauch davon ein...
Na wenn es so simple ist:
MS BspCode
public void Printing(string printer) {
try {
streamToPrint = new StreamReader (filePath);
try {
printFont = new Font("Arial", 10);
PrintDocument pd = new PrintDocument();
pd.PrintPage += new PrintPageEventHandler(pd_PrintPage);
// Specify the printer to use.
pd.PrinterSettings.PrinterName = "DerDrucker"; // <-- hier den Druckernamen eingeben
if (pd.PrinterSettings.IsValid) {
pd.Print();
}
else {
MessageBox.Show("Printer is invalid.");
}
}
finally {
streamToPrint.Close();
}
}
catch(Exception ex) {
MessageBox.Show(ex.Message);
}
}
Linker für Event
<A href="javascript:window.print()" onClick = "PrintThisPage()">Click here to print</a>
Und wenn es noch billiger sein darf, den Standarddrucker unter Windows umsetzen 😉
Hatte angenommen würdest eine Internetseite schreiben und wenn irgendwer dne Drucker xy besitzt soll eben dieser anspringen. Aber so, ists doch einfach 😮)
Na ja, wenn du Steuergeräte an einen Rechner anschließen kannst, könntest über einen Seriellen Port diese ansprechen und hier kommt dann C# ins Spiel.
Spracheingabe könntest z.b. jene von Windows Vista verwenden, siehe hierzu folgenden Link.
Na ja theoretisch gibt es ansonsten nichts zu beachten, evtl noch beim Touchdisplay gibt ja immer mehr diese Window Pokets mit Windows CE hier halt dann das MobileFramework von .net verwenden. Aber gibt auch Toucdisplays direkt am Rechner dran.
Schön wäre eine Zentralsteuerung so das die Displayes oder Poket PC's im Hause via WLAN auf einen Server zugreifen der die Steuerung über einen Widnowsdienst übernimmt. So das Anfragen aller Art in einer Que (Pool) landen und je nachdem Sequenziel abgearbeitet werden um somit Übersteuerungen bei den Geräten zu vermeiden - je nachdem wieviel im Hause "modernisieren" möchtest.
Na ja, das ist ja das Problem, es bringt dir nichts auf das Event zu reagieren 🙂
Du kannst vom Client nicht die Daten wie z.b. dessen Druckertreiber nicht auslesen. Das kannst ja nur machen, wenn dein Programm auf dem Client läuft.
Also wenn du grade bei dir lokal rumprogrammierst findest deien Treiber, sobald deine Internetseite auf dem Server gealden wird wirst sehen das es plötzlich nicht mehr geht und dein Systemadmin wundert sich das irgendwann mal z.B. 100 Dialoge aufleuchten auf dem Rechner mit Druckanfragen 🙂
Um das Problem zu umgehen muss auf den Clients ein Programm laufen das sich darum kümmert. Wenn du das eben nicht (wie hier eigentlich zu verwenden Java) verwenden möchtest sondern C# kannst du das über ein Plugin machen das die Internetseiten ausließt und so wie es dieses Autosign Tool auf Codeproject macht. Dabei schaust du nur bis irgend ein Tag kommt das Signalisiert ah hier Druckertreiber auslesen, und folgende Informationen ausdrucken. Es muss ja kein Tag sein, kannst auch etwas anderes dafür benutzen.
Im normalfall löst man so etwas am geschicktesten mit Java Servlets und Applets.
Eine billige trviale Lösung ist mir nicht bekannt wie Daten vom Client auslesen möchtest wie den Druckertreiber (Installierte Drucker usw.) 🙂
/PS
Das einzige was mich halt mit den Title von dir verwirrt ist, ob einen eigenen Webbrwoser schreibst oder nicht, da würde sich das ganze natürlich anders verhalten.
Na ja, das Beispiel zeigt ja auf wie man das Plugin erstellt und mehr als nen Event zu regestrieren und es mit dem Plugin auszulesen brauchst auch nicht. Wie man die Printersettings bedient steht hier im Forum sicher etliche male drinnen.
Eigentlich brauchst nur nen wenig herumzukopieren 🙂
Du kannst das auch anders lösen, wenn das nur bei deinen Kunden eingesetzt wird kannst es übers Serialiseren versuchen und einen Windowsdienst der die Rechenr innerhalb des jeweiligen Kundennetzwerkes ausließt was die so an Druckertreibern auf ihren Rechnern installiert haben und so versuchen das ganze zu lösen. Du kannst auch eine Anwendung schreiben die auf den Rechnern im Hintergrund läuft und an dieses Serialisierte Nachrichten z.B. über Sockets senden.
Du kannst auch anhand von JavaScript, Shell (mit VB) oder evtl. sogar Flash (Adobe ActionScript) versuchen das ganze zu lösen, da dieses ebenso Clientseitig ausgeführt wird - aber das wird beweiten schwerer.
Kannst auch direkt für bestimmte Browser über derne SDKS Plugins erstellen, sind ja nur DLLImports wie z.B. bei FireFox (download incl.) Link.
Hrm, bin leider kein spezialist darin aber normal werden zwei interop dlls erstellt:
<name>.dll und AX<name>.dll
Du brauchst AX<name>.dll zum initalisieren des Konstruktors.
Hrm, wenn es nur um die Lösung geht so kannst du die Windowsmessages global abfangen und jedesmal wenn WM_SETFOCUS (hex: 0x0007) abfangen und mit Win API SetFocus (siehe www.pinvoke.net) dann aufs das modale umlinken.
Praktisch ist, du musst an den globalen hook nicht noch das Handle übergeben vom Modalen Fenster, als lParam sollte bei WM_SETFOCUS das Handle des Fensters schon drinnen sein.
Globale Hooks findest hier im Forum etliche 🙂
Denk aber dran was JAck30lena schrieb, es muss wirklich Sinn machen sonst wird es für dne benutzer nervig.
Hrm, man muss dazu sagen das ErfinderDesRades eigentlich das ganze besser mit seinem Vorschlag für UserControls angeht. Der Vorteil liegt darin das UserControls eine wiederverwendbarkeit haben. Wenn also irgendwann mal Elemente nochmals benörigst und diese zudem ihre eigene BusienssLogic beinhalten brauchst du dieses Element nicht nochmals erstellen.
Schön ist z.B. ein solches vorgehen für Navigationsleisten. Statt mehrere Formualre zu kreieren. Ladest z.b. in ein Panel ein UserControl rein. Und schon spaarst dir das übliche MDI Controler rumgewurstel und sieht (wie ich finde) besser aus (vorallem der Code).
Hrm, um am Effektivsten mit der Windowsdokumentation zu arbeiten wie sie dir Th69für die winspool.drv gegeben hat. Klickst die jeweiligen Links der Druckerinformationen an. Wenn also z.B. den Link für PORT_INFO_1 anklickst, siehst dann oberhalb die erklärung und unterhalb davon ein "See Also: Printing and Print Spooler Overview, Printing and Print Spooler Structures, EnumPorts " wenn du diesen Link folgst oder teilweise diese Linknamen kopierst und auf www.pinvoke.net suchst bekommst du bereits die vorgefertigten Dll Imports + Beispiel wie man es verwendet.
Bei dir wäre das z.B. um die Ports auszulesen folgender Link.
Die Microsoftseiten sind übrigens alle so aufgebaut das unter "See Also" eigentlich immer den DLL Importnamen oder das Stichwort für den DLL Import findest. Somit braucht man theoretisch nichtmal die Dokumentation durchlesen, sondern gelangt sofort auf ein Codebeispiel(e) 🙂
Hrm, spontan würde ich sagen löse das über ein eigenentwickeltes Plugin für Webbrowser.
Das Plugin selbst ist nur in der lage da es sich lokal auf dem System befindet die Systemresourcen wie z.B. die verfügbaren Drucker auszulesen oder dort auch den / die Drucker anzusprechen. Über die Shcnitstelle die das COm object dann zur verfügung stellt kannst du im Browser an das Plugin das zu druckende Dokument naja (quasi) senden (einfache Events).
Siehe hierzu Codeprojekt: http://www.codeproject.com/KB/cs/autosig.aspx
Denke sollte einer der leichetren Wege sein und kannst damit die breitere Masse an Nutzern bedienen.
/PS
Denke wenn etwas im Forum rumstöberst unter Stichwörtern wie: "Webbrowser Plugin" findest sicher einiges 🙂
Was kommt als nächstes?
Das nächste was folgt ist der DockingControler.
Wichtiger Hinweis:
Der Code ist noch etwas unsauber, wird aber sobald alle Komponenten drinnen sind gesäubert und dokumentiert.
/PS
Leider dauert es noch etwas bis es wieder weiter geht 🙂
Hrm, glaube kommt immer drauf an was man mit den Zeichen verbindet.
Meine erste größere Liebe schrieb immer ein :-} daher verbinde ich dieses Zeichen als etwas Positives. Mit ^^ verbinde ich mit Ironie oder mit negativen Zusammenhängen.
Aber ich denke eine allgemeine Bedeutung für irgendwelche Zeichenfolgen gibt es nicht immer.
Hallo Comunity,
ich erstelle zur Laufzeit ein kleines UI Control das ein Form aufruft das dem Designer "Choose Resource" Dialog nahe kommt.
Innerhalb dieser Form möchte ich dem Programmierer erlauben "Image" Resourcen in seine gewählte Resourcendatei reinzuschreiben.
Der Codeauszug dafür:
private void ImportIntoResource()
{
string sRes = this.m_cbProject.SelectedItem as string; /// ->> "UtilitiesLib.Properties.Resources.resources"
///
if (string.IsNullOrEmpty(sRes))
{
MessageBox.Show("choose an resource to bind the data.");
return;
}
using (OpenFileDialog _dlg = new OpenFileDialog())
{
_dlg.Multiselect = true;
_dlg.Filter = "(*.jpg)|*.jpg|(*.bmp)|*.bmp|(*.gif)|*.gif|(*.png)|*.png";
_dlg.InitialDirectory = ".\\";
_dlg.RestoreDirectory = true;
if (_dlg.ShowDialog() == DialogResult.OK)
{
foreach (string _fn in _dlg.FileNames)
{
FileInfo fileInfo = new FileInfo(_fn);
if (fileInfo.Exists)
{
sRes = sRes.Replace(".", @"\");
sRes = sRes.Replace(@"\resources", ".resx");
sRes = string.Format(@"{0}\{1}", Environment.CurrentDirectory, sRes); // important: only design runtime!
using (IResourceWriter writer = new ResourceWriter(sRes))
{
Image img = Image.FromFile(fileInfo.FullName);
writer.AddResource(fileInfo.Name, img);
}
}
}
}
}
this.ListResource(sRes);
}
Das ganze lässt sich ausführen aber verursacht den Fehler das die Resourcendatei .rsx wohl ein anderes Format benutzt als die Methode ResourceWriter wohl erstellt.
Bei mir erscheint dann folgende Fehlermeldung:
Ungültige Resx-Datei. Ungültiges Zeichen in der angegebenen Codierung. D:\Entwicklung\SkinningTool\UtilitiesLib\Properties\Resources.resx
Die Frage ist nun, muss ich das Format der .resx Datei nacherstellen und den Stream selbst eintragen oder sollte der ResourceWriter es eigentlich erlauben in die bestehende Datei reinzuschreiben?
Das was mich wundert ist hauptsächlich die Dateiendung, die VS .resx Datei wird beim auslesen von resourcen immer mit Dateiendung ".resources" angezeigt. Steckt die Datei evtl. in der ".resx" Datei....
Vielen Dank im vorraus.
Hrm, naja die WM_PAINT Methode ist ja nicht die einzige WindowsNachricht die für die Zeichenroutine genutzt wird. WM_PAINT, WM_NCPAINT, WM_ERASEBKGND wären hierbei die wichtigsten.
Wenn du also die Panelfarbe veränderst ist nicht zwingend gesagt das die Nachricht nur in WM_PAINT verarbeitet wird. Dazu kommt das viele Controls wiederum Controls beinhalten. Und auch hier kann es sein das die Nachrichten dann eben in den jeweiligen Childcontrols abgearbeitet werden oder mal im Parent...
Informationen wie das Handle des DeviceContext oder die Region sind auch etwas schwer zu unterscheiden. Bei der Region wird wieder unterschieden zwischen ClientRegion und tazächlicher Fenstergröße WindowRect. Bei gewissen Funktionen wie WM_NCCALCSIZE kommt noch hinzu wo das Fenster sich zuvor befunden hat und wohin es quasi wandert.
Um exakte Informationen zu bekommen kommst nur mit einer systemweiten Abfrage auf die Handles des jeweiligen Fensters nicht weit. Du musst weiterfiltern, das macht ja die Windowsnachrichten zu verarbeiten so mühsam.
Die Frage ist halt nur was du genau vorhast und wie du die Nachrichten abfängst, ob SubClassing oder Hooks usw.
Also, wenn deinen Ansatz mit eben Khalid's Vorschlag (EnumChild Windows) kombinierst erhällst dein gewünschtes Resultat.
Hrm, brauche wohl doch noch nen weilchen 🙂
Aber soviel vorweg, der Designer ist erstmal wieder draussen - wird aber später wieder eingebaut. Was neu dazu kam ist eine Optimierung der NonclientBorder und ein möglicher Farbverlauf pro Border. Alternativ kann pro Border ein Bild verwendet werden das man verschiedenartig sizen kann. Die jeweilige die Größenanordnug funktioniert automatisch. Ebenso reingekommen ist eine Trennung zwischen Forms und Controls, dafür gibt es nun zwei Komponenten. Die Formkomponente kann mehrere Forms fassen die auf der aktuellen Ansicht liegen, daher die Trennung. Ebenso reinkamen Buttons die man ebenso wie die Borders designen kann und mit Befehlen oder Komandos versehen kann.
Derzeit bin ich am implementieren von Standardskins die man durch implementieren eines Interfaces erwweitern kann. Das erweitern funktioniert auf basis einer assembly die das Interface beinhaltet und in einen seperaten Ordner des Ausführungsverzeichnisses hinterlegt wird.
Tut mir leid das es so lange dauert aber ich denke in ein paar Tagen sollte es soweit sein, die anbindung in ein gemeinsammes SVN projekt erfolgt dann ein paar Tage darauf.
Also, etwas Geduld noch 🙂
Das klingt nichtmal schlecht, die Kostenlose variante mit 500 MB reicht mehr als gut aus 🙂
Hätte absolut nichts dagegen, muss mal schauen ob ich nicht irgendwoher nen Server dafür organisieren könnte und eben SVN 🙂
Hallo Community,
da ich die Idee von Thorsten1983 interessant fand eine Open source UtilitiesLib zu schreiben (siehe Eure Meinung zu : UtilitiesLib), möchte ich an dieser Idee weiter mitwirken.
Hierzu möchte ich im ersten Schritt folgende Punkte realisieren:
*Global Skinning Komponente für Controls
Eine Windowskomponente die sich auf bestehende Controls einklinkt und deren Nonclient wie Clientbereich anpasst. Das ganze wird dann über ein im Designer integriertes Tool zu steuern sein.
*Widgets
Windows Forms ähnliche Fenster die sich anhand eines DockingControls auf einer Form wie MDI's ausrichten und einrastern.
*DockingControler
Die Controler Componente für die Darstellung des Einrasterns der Widgets.
*Hooks -> darunter Fallen Mouse und keyboardevents wie Hotkeys
Globale Maus und Tastaturabfragen werden als Events anhand von Komponenten dem Programmierer zur Verfügung gestellt um z.B. auch über den Designer Events zu binden.
Stand: 13.05.08
So, zwar bin ich noch lange nicht fertig und den ein oder anderen Fehler gibt es noch aber ich denke aus dem Projekt wird klar wohin die Reise gehen soll.
Für was ist dieses Projekt da?
Prinzipiell geht es weniger bei dem Projekt darum „eine absolut fertige" Lösung anzubieten, als den Weg aufzuzeigen wie man die verschiedensten Controls und Designermethoden verwenden oder umgestalltet kann anhand der Windows API.
Was ist bisher drinnen?
Hinweise:
Designerunterstützung
Es gibt eine Designerunterstützung fürs global Skinning
Hierfür einfach auf die SkinForms Komponente klicken und dort unter der Kategorie "Sonstiges" und auf dien ComboBox Button bei "Skin" klicken.
Es gibt eine Designerunterstützung für jedes einzelne Form
Hierfür einfach das Formular anklicken unter der Kategorie "Skin" und auf den ComboBox Button bei "Border" klicken. Man kann dort aber auch manuell die Properties ändern. Das ändern von global Skins erfolgt auf allen Formularen.
Was bedeutet global Skinning?
Hierfür wird an jedes Formular (später auch Controls) ein Event gesendet das die aktuelle Ansicht zur Designerlaufzeit überschreibt, das geht allerdings nur wenn dafür die Designerunterstützung benutzt wird. Sinn und Zweck des ganzen ist das wenn jedes Formular diesen Skin als Information selbst speichert, man für vielleicht ein Form das anders aussehen soll als alle anderen man dieses wiederum verändern kann durch die Designerunterstützung für nur dieses Form - vielleicht ändere ich hier das ganze auch noch über Resourcen.
Was für Skins gibt es bisher?
Leider bin ich kein großer Pinsler und Maler, somit gibt es nur einen Skin namens Blue von mir. Wer möchte kann aber gerne über das Skin Blue Beispiel eigene Skins hinzufügen. Allerdings, wird das ganze nochmals bearbeitet.
Warum Border Top und Border Teaser?
Border Teaser erlaubt es ein Bild zusätzlich als "Titelbild" zu implementieren und wird grundsätzlich vor BorderTop gezeichnet. Somit kann man links mittig oder rechtsbündig zusätzlich ein Bild in der Titelleiste anzeigen, z.B. ein Wasserzeichen mit den Firmenlogo darauf.
Warum Border Hittest?
Der Borderhittest gibt das Verhalten der Border zurück. Man kann somit das Sizen an jeder Beliebigen Border verhindern oder anstattdessen andere aktionen auslösen. Ebenso kann man den Offset beinflussen inwieweit man mit der Maus den Rand anklicken kann.
Warum UseWindowTheme?
Möchte man das aktuelle Windows Theme aktiviert lassen, so kann man dies pro Windows Form einstellen. Kanten können somit auch bei Varbverläufen abgeflacht werden, allerdings muss man hierbei die Größenporportionen manuell beachten.
Was ist MouseHook?
Eine Komponente mit Designerunterstützung die folgende Mausnachrichten Systemweit abfängt und in einem MouseEvent wiedergibt:
Was ist KeboardHook?
Im Prinzip das selbe wie Mousehook nur für Tastatureingaben:
Was ist HotKey?
HotKey ist eine Komponente welche es erlaubt Tastenkombinationen auf Controls zu legen, welche beim auslösen ein Event schmeißt.
Hierzu ein kleiner Hinweis: Leider habe ich es noch nicht geschafft den Designersupport dafür umzusetzen. Wer also die Komponente nutzen möchte, zieht sie ganz normal auf das Form und spricht die Komponente im Code noch manuell an. Es bringt daher noch nichts in der Auflistung auf dem Propertygrid HotKeys hinzuzufügen. Dieser Fehler wird allerdings noch behoben.
Was ist ein Widget?
Ein Windows Widget ist ein Fenster im Fenster, das sich an dem Parentfenster orientiert. Das bedeutet im Klartext, das anhand der Position des Fensters ermessen wird ob das Fenster in eine gewisse logische Richtung verschoben werden darf. Ein Widget kann wiederum Widget's beinhalten usw.
Gibt es das Widget auch in bunt?
Man kann es genauso wie die SkinForms selbst bemalen wie man Lust und Laune hat und so ziemlich sämtliche Eigenschaften beeinflussen. Und man kann es mit SkinForms sogar mit den globalen Skinning bemalen.
Kann ich auf mein Widget Controls adden?
Ähnlich wie auf ein Panel positioniert man seine Elemente darauf und kann diese bearbeiten.
Wie siehts mit der Positionierung zur Laufzeit aus?
Wenn die Eigenschaft AutoIntelligence auf true gesetzt ist so passt sich das Widget an seinem Dockingverhallten an. Wenn diese Eigenschaft auf false gestellt ist, kann man das Widget wie im MDI hin und her bewegen – der Effekt tritt auch dann auf wenn das Widget auf DockingStyle.None gestellt ist.
Was fehlt den Widget's noch?
Für das Docking verhallten erstelle ich noch ein DockingControl das bei AutoIntelligence false dafür verantwortlich ist, dass Widget beim ziehen automatisch an der gewünschten Possition zur Laufzeit einzurasten.
Ansonsten, wünsche ich viel Spaß beim rumprobieren 🙂
Super vielen Dank 🙂
Hallo Comunity,
ich schreibe zurzeit ein kleines Programm für das Skinning von Controls aller art. Um nun die erweiterten Einstellungsmöglichkeiten der Controls darzustellen möchte ich dem Programmierer das Skinning erleichtern. Hierfür gibt es die Möglichkeit ein globales Skinning vorzunehmen wie ein nur für das Control spezielles.
Damit dass ganze für den Programmierer erleichtert wird, wollte ich im VS Designer eine ComponentEditorPage Aufrufen. Soweit klappt das auch - das einzige was mir fehlt, bei vielen Designern gibt es auf der Propertiepage soetwas wie "Run Designer" "View Designer" "Add Controls" als Links die man drücken kann und dann öffnet sich im Designer das ComponentEditorPage.
Leider finde ich unter System.ComponentModel irgendwie nicht das passende Attribut dafür 🙂
Suche natürlich weiter, aber vielleicht weis es ja jemand. Wie es funktioniert finde ich dann schon heraus, suche nur das Stichwort 🙂
Vielen Dank im Vorraus!
Hrm, hatte da nur mal mit dem Windows Styles etwas rumgespielt und bin zufällig drüber gestolpert. Aber was damit zusammenhängt war mir nicht so ganz klar.
Werd's einfach wenn ich Zeit habe mal austesten wie das ganze AERO Thumbnails so funktioniert, danke dir jaensen 🙂
Also, JunkyXL wirst JAck30lena's Lösung verwenden müssen sonst bekommst Probleme unter älteren Betriebssystemen als Windows Vista.
Na ja das Zeigt ja das "glückliche" Menschen die Software nutzen und es sich nicht ums neue Pokemon update 1.1 handelt. Nen bisschen Augenwischerei darf immer dabei sein, ist wie mit nen Splashscreen, wenn da nur "Willkommen, ihre Software wird nun geladen..." erscheint wäre das ja auch langweillig 🙂
Und Bürömenschen vermitteln ja etwas von Business... Ach keine Ahnung bin nen Programmierer kein Designer 😉
Achso, noch nen Tipp lass Tiere weg.
Schlimm genug das so nen Pinguin nen OS herhalten muss - oder haben Pinguine ein OS?
Mal ersnthaft, bei manchen Softwarelösungen frage ich mich ob ich nicht grade eben bei Toys "R" Us nen Stofftierchen gekauft habe und muss mich zweimal vergewissen das es genau die Software war die ich haben wollte 😉
Verpackung sollte eindeutig Signalisieren was steckt drinnen.
Hrm, bunte Software zieht denke ich am meisten dann erst kommt die Funktion (traurig aber was ich bsiher so erlebt habe...).
Mach doch Screenshoots von den Buntesten stellen deines Programms bzw. an den Stellen an denen deine Software etwas bietet was die anderen Softwarehersteller nicht haben. Das ganze bildet dann die Rückseite mit den üblichen "Unsere Software bietet ihnen absolutes rundum wohlfühlaroma.. bla bla".
Für die Frontansicht suchst dir nen paar gut aussehende Büromenschen M / W gemischt die über nen Tisch sich beugen und lächeln während sie deine Software bestaunen oder so tun als würden sie diskutieren. Am besten nen steriler Bürohintergrund, dazu alles gut und hell beleuchtet, die Software läuft natürlich gut sichtbar auf einen Flatscreenmonitor im Vordergrund der Personen.
Sieh dir mal die SAP Verpackung an, ungefähr sowas in der Art.
Mach nicht den Fehler und zeig nen grinsenden Programmierer, die will niemand sehen 😉 Für das Layout such dir ein professionelles Lithostudio und Reprostudio (ja die gibt es nicht und die lege ich dir wirklich nahe) und eine passende Druckerei, meistens regelt das aber dass Reprostudio oder ist eh schon ne Druckerei.
Hrm, es da nen Schalter dafür gibt weis ich nicht.
Hätte einfach grob eine neue Klasse erstellt von DataGridView abgeleitet und die OnKey oder Validate Methoden mir mal angesehen. Mit dem Focus herumzuliebäugeln solltest besser sein lassen, sollte zwar auch gehen aber das geht meistens schief.
Beim Validieren oder beim Drücken der Tabtasten oder der Pfeiltasten würde ich schauen auf welches logische nächste Feld gesprungen wird und dann ersteinmal prüfen ob das Feld ReadOlny ist, wenn nein geht der Tab ganz normal weiter. Ansonsten mogle ich enwteder über WinAPI PostMessage nochmal nen TAB dazwischen oder schaue mir mal an was DataGridView zu bieten hat, evtl gibt es da nen MoveNext() oder MovePreview usw.?
private void Formular_MouseMove(object sender, MouseEventArgs e)
{
if (betrieb == 0)
{
SymbolName(new Point(e.X, e.Y));
}
}
private void SymbolName(Point pt)
{
//toolTip.Hide(this);
bool bFound = false;
foreach (Symbol sym in this.symbol)
if(sym.pt.Contains(pt))
{
bFound = true;
break;
}
if(!bFound) toolTip.Hide(this);
}
Dreh einfach das ganze um.
Also JAck30lena hat schon den Nagel auf den kopf getroffen, die LiveAnsicht wird natürlich immer wieder aktuallisiert z.B. über einen zeitlichen Intervall.
Deswegen meinte er auch "Vorsicht" mit der Performance, denn die Zeichenroutine muss ständig geleert und neu gezeichnet werden mit DrawToBitmap das kann evtl. in die Performance gehen.
Der schwerere Weg mit selben "Erfolg" wäre folgender, du klaust dir das Vista verhallten.
Um erstmal das verhallten zu imitieren muss man erst einmal herausfinden wie man es provoziert, denn das weis ich grade nicht.
Bastle ein neues Projekt und erstelel Form1, überschreibe CreateParams, übergebe an CreateParams cp den cp.StyleEx|= WindowsStyleEx.WS_EX_APPWINDOW siehe hierzu www.pinvoke.net. Überwache mit dem Spy++ das Fenster und beobachte die Taskleiste dazu mit. Schau dir an ob die Taskleste die zeichenroutine zur verfügung stellt oder ob das Fenster selbst diese auslöst.
Wenn die Taskleiste das Zeichnen übernimmt kommst um JAck30lena (besseren) Weg nicht drum herum. Ansonsten überschreibst in deinenControl ebenso die CreateParams und fügst den StyleEx WindowsStyleEx.WS_EX_APPWINDOW an. Und schaust was passiert wenn das Control "den zustand" minimiert erhällt. Sieht dann lustig aus nen minimiertes nicht sichtbares Control das aber da ist um nen Fenster anzuzeigen, die WindowsNachricht WM_ACTIVATE müsste dafür verantwortlich sein und da diese auf den Msg.Return Intptr.Zerofür False und 1 für True reagiert hängst einfach ne Methode dazwischen die du je nachdem ob die Maus eine gewünschte Aktion ausführt auf False ( Intptr.Zero) oder True ( new Intptr(1)).
Also, denke das JAck30lena's Lösung bewieten weniger kompliziert ist und sogar zuverlässiger arbeitet.
Dafür gibt es ebenso ein Event "Leave" kannst das aber auch auf andere weise lösen 🙂