Strukturbaum/Tree View/Explorer
-
die frage war wirklich n witz!
ich dachte mir eure beiträge wären wohl gut für die, die das nach mir suchen und auf dieses forum stoßen!danke für die links

-
Musst dich nicht schämen. Wirst ja dafür nicht ausgelacht.
ABER DAFÜR:
noPeil schrieb:
ich dachte mir eure beiträge wären wohl gut für die, die das nach mir suchen und auf dieses forum stoßen!

-
Ich versuche gerade ein Treeview zu erstellen und gebe bei case WM_INITDIALOG: den code wie er im tutorial (http://www.codeproject.com/KB/tree/treeview.aspx) beschríeben ist ein, nur um zu testen ob es funktioniert. allerdings wird mir nur mein textfeld angezeigt ohne treeview
Was mache ich Falsch?
-
Was Du falsch gemacht hast?
Woher sollen WIR das wissen?
Und was hast Du bisher an Erfahrungen gesammelt?Ein Control wie TreeViwe ist relativ komplex, da kann man prinzipbedingt viele Fehler machen.
Und das hat man als Anfänger nicht in 30min mit allen Optionen zusammengestrickt. Auch ich damals.Deshalb erstmal Grundlagenwissen:
MSDN-Original Doku Startpunkt "Tree View": http://msdn.microsoft.com/en-us/library/bb759988(v=VS.85).aspxAllgemeine Erklärung: "About Tree-View Controls" http://msdn.microsoft.com/en-us/library/bb760017(v=VS.85).aspx
Und speziell: "Using Tree-View Controls" http://msdn.microsoft.com/en-us/library/bb773409(v=VS.85).aspx
Ist beinahe eine Step-by-step Anleitung. Damit müßtest Du eigentlich klarkommen, vorausgesetzt Du kannst etwas englisch...HTH,
Martin
-
Ja Danke für die Links schon mal, die haben mir echt geholfen, meine vorherigen Quellen waren einfach schlecht und es gab kaum welche...
mein nächstes problem ist: eine Aktion (bzw Erscheinen von strings im anderen Fenster) soll geschehen bei Doppelklick auf das letzte element.
hättet ihr hierzu auch tipps?
-
Bei Doppelklick auf ein Element im TreeView wird der Parent (!) von Deinem TreeView mittels NM_DBLCLK http://msdn.microsoft.com/en-us/library/bb773475 benachrichtigt.
Dazu wertest Du die Nachricht WM_NOTIFY aus, in dieser prüfst Du den Inhalt auf NM_DBLCLK.Für Doppelklick mit rechter Maustaste ist es ähnlich: NM_RDBLCLK http://msdn.microsoft.com/en-us/library/bb773488
HTH,
Martin
-
gibt es eine operation für childwindows, welche die größe automatisch an das hauptfenster anpasst.
Wenn ich z.b. das fenster größer ziehe, das meine beiden childfenster mitgehen und die scrollleisten nicht auf einer höhe hängen bleiben.also ich habe zwei childwindows in einem hauptfenster generiert.
danke für die antworten

-
Du musst im Parent auf WM_SIZE reagieren und mit MoveWindow/SetWindowPos die Childs neu positionieren.
-
Danke!
weiteres problem :(.....ich hab zwei childwindows im hauptfenster generiert, das eine soll ein texteditor sein das andere strukturbaum!
WndProc(..)
case WM_CREATE:
{
hText = CreateWindowEx ( WS_CLIENTEDGE,L"Edit", L"",
WS_CHILD|WS_VISIBLE|WS_VSCROLL|WS_HSCROLL|
ES_MULTILINE|ES_AUTOVSCROLL|ES_AUTOHSCROLL,
500,0,600,700,hWnd,(HMENU)IDC_MAINEDIT,
GetModuleHandle (NULL),NULL);trotzdem beginnt der editor oben links im eck und überschreibt quasi das fenster für den Strukturbaum, kann mir jemand sagen was ich falsch mache?
-
Ich setze mal voraus, die beiden Childfenster (TreeView + Edit) werden beide jeweils im WM_CREATE des Parent-Windows nacheinander erzeugt.
Die Reihenfolge ist egal (TreeView zuerst, dann Edit oder auch umgekehrt).Hast Du sichergestellt, daß das Parent-Window groß genug ist?
(Muß laut Deinem Code 500+600 Pixel plus Fensterrahmen breit sein!!!)Übrigens, man sollte grundsätzlich die tatsächliche hInstance von der Applikation verwenden statt wie bei Dir verwendet GetModuleHandle(NULL)!
Martin
-
Mmacher schrieb:
Übrigens, man sollte grundsätzlich die tatsächliche hInstance von der Applikation verwenden statt wie bei Dir verwendet GetModuleHandle(NULL)!
Das Handle wird dir bei WM_CREATE geschickterweise per LPCREATESTRUCT (LPARAM ist ein Zeiger auf ein CREATESTRUCT) übergeben.
-
die größe ist beachtet , der cursor blinkt weiterhin oben links hier mal ein ausschnitt:
int WINAPI WinMain(...)
....
hWnd = CreateWindow ( szAppName,szAppName,
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
CW_USEDEFAULT,
900,
800,
NULL,
NULL,
hInstance,
NULL);ShowWindow (hWnd, iCmdShow);
UpdateWindow (hWnd);
....LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
static HWND hText;
//static HWND hTree;
//static RECT rect;
int wmId, wmEvent;
PAINTSTRUCT ps;switch (message)
{
case WM_CREATE:
{
//int statwidths[] = {100, -1};hText = CreateWindowEx(WS_EX_CLIENTEDGE, L"EDIT", L"",
WS_CHILD| WS_VISIBLE |
WS_VSCROLL | WS_HSCROLL |
ES_MULTILINE|ES_AUTOVSCROLL|
ES_AUTOHSCROLL|ES_LEFT,
505,0, 495, 700, hWnd,NULL,
((LPCREATESTRUCT)lParam)->hInstance,NULL);if(hText == NULL){
MessageBox(hWnd,
L"Fehler beim Erstellen des Textfelds",
L"Fehler", MB_OK | MB_ICONERROR);
}hTree = CreateWindow ( szTree,
0,
WS_CHILD|WS_VISIBLE,
0,0,500,700,
hWnd,
NULL,
((LPCREATESTRUCT)lParam) ->hInstance,
NULL);
return 0;
}
-
Hi noPeil,
eines vorneweg: Bitte versuche Deinen Quellcode mit dem Button "C/C++" (unterhalb des Nachrichtentexts) formatieren.
Dann können wir Deinen Quelltext wesentlich angenehmer lesen.Nun zu Deinem Code:
int WINAPI WinMain(...) .... hWnd = CreateWindow ( szAppName,szAppName,Verwende bitte einheitlich CreateWindowEx(), wie bei den Child-Windows.
... CW_USEDEFAULT, CW_USEDEFAULT, 900, 800, ...Ich habe in meiner bisherigen Erfahrung für alle 4 Werte immer entweder CW_USEDEFAULT oder immer definierte Zahlenwerte verwendet.
D.h. ich kann Dir nicht sagen ob eine Mischung aus CW_USEDEFAULT und Zahlenwerte problemlos ist.noPeil schrieb:
die größe ist beachtet , der cursor blinkt weiterhin oben links
Wie hast Du das überprüft?
Dein Edit-Control benötigt 505+495=1000 Pixel Platz in der Breite, Dein Frame-Window hat aber nur 900 Pixel!
Mach mal bitte erstmal Dein Edit-Control klein genug, sagen wir mal 200x200 Pixel.
Das gleiche in etwa für das TreeView. Das reicht erstmal für den Anfang, um zu sehen daß es klappt.Martin
-
Eigentlich sollte das so klappen, probier aber auch mal Folgendes:
case WM_SIZE: GetClientRect(hWnd, &rect); MoveWindow(hTree,0,0,rect.right/2-2,rect.bottom,1); MoveWindow(hEdit,rect.right/2+2,0,rect.right/2-2,rect.bottom,1); break;Die IDs für die Controls sind nicht gesetzt, Absicht (zu ändern durch den HMENU Parameter oder durch SetWindowLongPtr(hEdit,GWL_ID, IdDesControls); )?
@Mmacher Feste Werte statt CW_USEDEFAULT gehen imho nur paarweise, also wenn die x-Position fix ist, dann muss es die y-Position auch sein, analog Breite und Höhe).
-
Vicious Falcon schrieb:
Die IDs für die Controls sind nicht gesetzt, Absicht?
Ja, das habe ich übersehen.
Gib den Controls jeweils unterschiedliche ID's, z.B. 106 für Edit, 107 für TreeView.
Idealerweise stehen die Definitionen für diese ID's in der resource.h, welche Du manuell oder über Resourcen-Editor ergänzen kannst.Vicious Falcon schrieb:
@Mmacher Feste Werte statt CW_USEDEFAULT gehen imho nur paarweise, also wenn die x-Position fix ist, dann muss es die y-Position auch sein, analog Breite und Höhe).
Danke für die Info!
Martin
-
Danke für eure Antworten,
also mit WM_SIZE:
Movewindow....
klappt das! das ist super!kann ich jetzt eigentlich auch ein Fenster im Fenster machen. Wenn ich in der TreeProc() (ist ein childwindow), wieder ein CreateWindowEx in WM_CREATE aufrufe klappt das wieder nicht ganz. wahrscheinlich muss ich wieder WM_SIZE überarbeiten.
Wenn ich allerdings im ChildWindow TreeProc() bei WM_PAINT ein createWindowEx () aufrufe, dann zeigt mir das Fenster die Baumstruktur an, nur ich glaube nicht dass WM_PAINT dafür gedacht ist :), wiederum befindet sich im ersten moment die Baumansicht im hintergrund, erst bei klick auf die Fenstergegend tritt es zum vorschein.
-
Also ich persönlich finde das immer unschön, viele Elemente per CreateWindow zu erzeugen und sich auf dem Papier die Positionen aufzumalen.
Man kann auch gleich alles im Dialogeditor von MSVS erstellen. Du könntest also auf deine linke Seite einen Dialog, der die Treeview, Buttons, etc. enthält, schieben, auf die rechte Seite kommt dann das Textfeld.
Falls die Standardhintergrundfarbe ein Hindernis darstellen sollte, kannst du dir mal die Nachricht WM_CTLCOLORDLG anschauen.
Ich sehe gerade, du hast gar nicht geschrieben, was das für Fenster sein sollen.
-
oh man ich wusste gar nicht das es diese option auch gibt, ich dachte die resource-datei ist auch code, also kann sie zumindest sein.
Jedenfalls hab ich jetzt beispielsweise meinen treeview so erstellt wie du gemeint hast die resource heißt IDD_DIALOGBAR, soweit ok!
wie kann ich diesen treeview jetzt in meinem fenster positionieren und im c-code aufrufen, ich bin noch ziemlich grün hinter den ohren was winapi angeht
verzeiht mir 
ich hab mir gedacht ich rufe im childwindow bei WM_CREATE:
DialogBox(hInst, MAKEINTRESOURCE(IDD_DIALOGBAR), hWnd, Tree);
auf!
nur dann kommen linker fehler
-
Das Problem ist, dass DialogBox einen modalen Dialog erstellt, also einen, mit dem die eigene Anwendung blockiert ist (genau, wie bei Aufruf von MessageBox).
Die Lösung ist CreateDialoghwndDlg = CreateDialog(hInst, MAKEINTRESOURCE(IDD_DIALOGBAR), hWnd, DlgProc);Die Hauptnachrichtenschleife sollte auch noch angepasst werden.
Die angegebene DlgProc verwaltet ihre Elemente selbständig. WM_SIZE kann hier benutzt werden, die Treeview passend innerhalb des Dialogs zu positionieren; wenn sich die Größe des Dialogs aber nie ändert, ist es nicht nötig, sondern kann direkt im Resourceneditor bestimmt werden.
Um das nutzen zu können, muss user32.lib gelinkt werden, was aber standardmäßig der Fall ist.
Edit : Falls der Dialog nicht sichtabr sein sollte, entweder ShowWindow(hwndDlg,SW_SHOW) aufrufen oder gleich im Editor das Flag WS_VISIBLE setzen.
-
der linker fehler bleibt allerdings weiterhin, alle lib´s sind eingebunden