PDA

View Full Version : [c++] api aggiornare testo


Mattyfog
20-08-2008, 18:36
Ciao,

sto lavorando in c++ con le api. Premetto che sto lavorando con i file .rc per la grafica (in quanto non conosco gli altri comandi che si inseriscono direttamente nel codice sorgente).
Volevo sapere se potete dirmi come aggiornare del testo in una dialogbox.
Infatti ho creato una libreria che copia una directory e vorrei che visualizzasse una dialogbox con scritto qualcosa del tipo

Avanzamento:

numero file copiati/numero file totali

grazie ciao

cionci
20-08-2008, 20:19
Ottieni l'HWND a partire dall'id della risorsa con GetDlgItem e poi usi l'api SetWindowText.

71104
20-08-2008, 22:29
Ottieni l'HWND a partire dall'id della risorsa con GetDlgItem e poi usi l'api SetWindowText. esiste SetDlgItemText (http://msdn.microsoft.com/en-us/library/ms645521(VS.85).aspx)

Mattyfog
20-08-2008, 23:29
riguardo la seconda opzione proposta è giusto usarla in questo modo?
SetDlgItemText(hWnd, IDC_LTEXT_PROGRESS, "pippo");
perchè il compilatore dice

E:\Documents and Settings\Matteo\Documenti\C++\nonno\Copia immagini\copymydir.h|109|error: `hWnd' was not declared in this scope|

DanieleC88
21-08-2008, 01:10
Hai semplicemente usato un nome sbagliato di variabile che non è definita nella funzione che usi. ;)
Assicurati che la variabile hWnd sia esattamente quella che indica la finestra in questione (e, ovviamente, che sia dichiarata e correttamente inizializzata :D).

Mattyfog
21-08-2008, 08:50
Hai ragione ma come faccio se voglio utilizzare questa funzine al di fuori "del ciclo" (non mi viene la parola) del mio dialogo? cioè esiste un funzione che "imposta" l'handle?

DanieleC88
21-08-2008, 10:47
Se usi quella chiamata dall'interno della funzione di callback che gestisce la finestra di dialogo, allora puoi recuperare quel valore dai parametri della funzione (è il primo parametro passato alla funzione, se non ricordo male).

Altrimenti se devi ricordarlo dopo la creazione della finestra devi salvare quel valore da qualche parte, magari passandolo tra i parametri delle funzioni che ne hanno bisogno se proprio è necessario.

ciao ;)

Mattyfog
21-08-2008, 11:19
il problema è che io devo richiamare una funzione senza mai passare dalla DialogProcedure, ti spiego guarda questo codice:

void copymydir(char *percorso, char *percorso2, BOOL &result, BOOL &delall)
{
DialogBox(GetModuleHandle(NULL), MAKEINTRESOURCE(IDD_DIALOG3), NULL, AboutDlgProc);


//qui c'è altro codice....


copyallfile(result);//questa è la funzione alla quale devo passare l'handle

}

il punto è (come posso dire,) che siccome la funzione non viene richiamata dalla Dialog Procedure, non so come poter passare l'handle a copyallfile.

DanieleC88
21-08-2008, 13:00
Allora, innanzitutto dovresti controllare che la finestra di dialogo sia stata creata correttamente:
if (DialogBox(/* ...parametri... */) == IDOK)
{
/* copia tutti i file */
}
else
{
/* stampa un messaggio di errore */
}

Comunque, hai una procedura di callback impostata:
DialogBox(GetModuleHandle(NULL), MAKEINTRESOURCE(IDD_DIALOG3), NULL, (DLGPROC)AboutDlgProc);
Quindi il primo parametro di AboutDlgProc() è l'handle della finestra di dialogo appena creata: se il tuo interesse è solo impostare del testo, lo puoi fare mentre la finestra viene creata gestendo quel messaggio con la tua funzione di callback e lasciando il resto dei messaggi al gestore di default:
INT_PTR CALLBACK DialogProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch (uMsg)
{
case WM_INITDIALOG:
/* fai quello che devi fare */
break;
}
return FALSE;
}

Mattyfog
21-08-2008, 14:45
in realtà io vorrei creare una finestra che aggiorni continuamente il testo, e siccome la funzione che riguarda la copia dei file è al di fuori della Dialog Procedure, avrei bisogno se possibile di richiamare SetDlgItemText da un'altra funzione ma non riesco... comunque adesso cerco una soluzione alternativa "spostando le funzioni", voi intanto ripondete...
ciao e grazie

Mattyfog
21-08-2008, 14:52
esite una funzione che ricavi l'handle di una dialog box pertendo dal suo ID???
così dovremmo essere a cavallo...

cionci
21-08-2008, 15:03
in realtà io vorrei creare una finestra che aggiorni continuamente il testo, e siccome la funzione che riguarda la copia dei file è al di fuori della Dialog Procedure, avrei bisogno se possibile di richiamare SetDlgItemText da un'altra funzione ma non riesco... comunque adesso cerco una soluzione alternativa "spostando le funzioni", voi intanto ripondete...
ciao e grazie
Ricava l'handle alla dialog item tramite GetDlgItem e poi passa l'HWND alla tua funzione. In quel modo puoi usare SetWindowText per settare il testo.

DanieleC88
21-08-2008, 15:10
Be' allora non puoi farlo in quel modo: DialogBox() crea la finestra di dialogo, la visualizza, reagisce agli input e ti dà il codice relativo all'input dato (nel mio esempio, IDOK perché suppongo che l'utente abbia premuto "Ok" per confermare, ma poteva dirmi "Sì" e io ottenere IDYES). Quindi non ho capito di preciso come dovrebbe visualizzarti i file in trasferimento. :D

Direi che puoi fare in due modi: evitare DialogBox() e chiamare CreateDialog() per ottenere anche l'handle e usarlo come ti pare. L'alternativa è creare una semplice finestra figlia modale e avere ancora più libertà d'azione.

ciao ;)

DanieleC88
21-08-2008, 15:13
Ricava l'handle alla dialog item tramite GetDlgItem e poi passa l'HWND alla tua funzione. In quel modo puoi usare SetWindowText per settare il testo.
Ma GetDlgItem() non recupera solo l'handle dei controlli interni alla finestra? Che però sì, in effetti può farlo se ha bisogno di cambiare solo un'etichetta... :D

Mattyfog
21-08-2008, 15:28
ciao
ho trovato la soluzione, daniele hai ragione su entrambe le cose che sono comunque riuscito a risolvere creando una sorta di toolbar (che comunque sembra una finestra).
Oral'ultimo problema off-topic:
guardate questa funzione:

oid copyallfile(BOOL &result)
{
vector<string>::iterator a = listaofile.begin();
vector<string>::iterator b = listadfile.begin();
while(a != listaofile.end())
{

copymyfile((*a).c_str(), (*b).c_str(), result);

a++; b++;

cout<<*a<<endl; //visualizza il file di origine

SetDlgItemText(g_hToolbar, IDC_TEXTPROGRESS, a); //funzione per cambiare il testo che non funziona, l'errore è causato dalla variabile a;


}

}


allora io ho queste 2 variabili (a , b) che mi permettono di usare i due vettori che contengono strignhe che indicano l'origine e la destinazione dei file da copiare.
Siccome penso che a e b indichino la posizione nei vettori (ne sono sicuro se no non si implementerebbero per passare alla stringa successiva!!!) vorrei sapere come posso visualizzare il loro valore (numerico) nella finestra che ho creato perchè come ho scritto io non funziona.
Ciao e grazie dell'aiuto che mi state dando!!!

cionci
21-08-2008, 15:30
a->c_str()

Mattyfog
21-08-2008, 15:41
quello va bene ma per visualizzare la stringa del vettore, non per visualizzare a (inteso come numero).
Quindi???

cionci
21-08-2008, 16:08
????
Il terzo parametro deve essere un LPCTSTR...quindi non puoi passare un puntatore alla classe string.
In teoria ci sarebbero altri casini sulla conversione a wide char e così via, intanto inizia così.

Mattyfog
21-08-2008, 16:12
e allora come faccio a far vedere quanti file ho già copiato???

cionci
21-08-2008, 16:19
Non è che ti eri spiegato molto bene ;)
a e b sono iteratori e non contatori.


void copyallfile(BOOL &result)
{
vector<string>::iterator a = listaofile.begin();
vector<string>::iterator b = listadfile.begin();
int counter = 0;
while(a != listaofile.end())
{

copymyfile((*a).c_str(), (*b).c_str(), result);

a++; b++; counter++;

cout<<*a<<endl; //visualizza il file di origine

ostringstream<TCHAR> counterText;
counterText << counter;

SetDlgItemText(g_hToolbar, IDC_TEXTPROGRESS, counterText.str()); //funzione per cambiare il testo che non funziona, l'errore è causato dalla variabile a;


}

}

Mattyfog
21-08-2008, 16:37
ho scritto come te ma mi da 2 errori:

E:\Documents and Settings\Matteo\Documenti\C++\nonno\Copia immagini\copymydir.h|114|error: `std::ostringstream' is not a template
E:\Documents and Settings\Matteo\Documenti\C++\nonno\Copia immagini\copymydir.h|114|error: aggregate `std::ostringstream counterText' has incomplete type and cannot be defined

non c'è una libreria da includere???

cionci
21-08-2008, 16:46
Aspetta che guardo meglio.

cionci
21-08-2008, 16:51
In effetti...

basic_ostringstream<TCHAR>

Mattyfog
21-08-2008, 17:24
sulla stessa riga adesso ho questo errore:

E:\Documents and Settings\Matteo\Documenti\C++\nonno\Copia immagini\copymydir.h|114|error: aggregate `std::basic_ostringstream<char, std::char_traits<char>, std::allocator<char> > counterText' has incomplete type and cannot be defined|

cionci
21-08-2008, 17:27
Hai aggiunto #include <sstream>

cionci
21-08-2008, 17:37
Se non funziona prova così:

basic_ostringstream<TCHAR, char_traits<TCHAR>, allocator<TCHAR> > counterText;

Mattyfog
21-08-2008, 18:51
sempre stesso errore(penso):

E:\Documents and Settings\Matteo\Documenti\C++\nonno\Copia immagini\copymydir.h|114|error: aggregate `std::basic_ostringstream<char, std::char_traits<char>, std::allocator<char> > counterText' has incomplete type and cannot be defined|

cionci
21-08-2008, 18:54
Strano...ho controllato ed in molti danno quel codice.
Vista la sostituzione di TCHAR con char....fai così:
ostringstream counterText;

Mattyfog
21-08-2008, 19:06
ciao,
scusa che stupido questo metodo funzionava, solo che non avevo incluso la libreria che mi hai detto!!! scusa

ostringstream counterText;
counterText << counter;
SetDlgItemText(g_hToolbar, IDC_TEXTPROGRESS1, counterText.str());

con funzionava intendo che la prime 2 righe vanno ma l'ultima da il seguente errore:

E:\Documents and Settings\Matteo\Documenti\C++\nonno\Copia immagini\copymydir.h|117|error: cannot convert `std::basic_string<char, std::char_traits<char>, std::allocator<char> >' to `const CHAR*' for argument `3' to `BOOL SetDlgItemTextA(HWND__*, int, const CHAR*)'|

cionci
21-08-2008, 19:13
E se torni al penultimo che ti ho detto funziona con la libreria inclusa ?

basic_ostringstream<TCHAR, char_traits<TCHAR>, allocator<TCHAR> > counterText;

Se non funziona fai una conversione esplicita a LPCTSTR:

(LPCTSTR)counterText.str()

Mattyfog
21-08-2008, 19:16
ho fatto entrambe le cose ma:

E:\Documents and Settings\Matteo\Documenti\C++\nonno\Copia immagini\copymydir.h|117|error: cannot convert `std::basic_ostringstream<_CharT, _Traits, _Alloc>::str() const [with _CharT = char, _Traits = std::char_traits<char>, _Alloc = std::allocator<char>]()' from type `std::basic_string<char, std::char_traits<char>, std::allocator<char> >' to type `const TCHAR*'|

cionci
21-08-2008, 19:22
Sorry:


(LPCTSTR)counterText.str().c_str()

DanieleC88
21-08-2008, 19:27
Madonna quante conversioni. :asd:

Mattyfog
21-08-2008, 19:38
ok adesso va!!!
già che ci sei mi sai dire come ricavare la grandezza totale di un vettore?

cionci
21-08-2008, 19:43
http://www.cplusplus.com/reference/stl/vector/

Se devi creare una stringa da mettere nel dialogo puoi usare sempre l'ostringstream come fosse un cout, ad esempio:

counterText << counter << "/" << a.size();

Mattyfog
21-08-2008, 19:54
so che stiamo andando molto fuori topic ma questa è veramente l'ultima domanda(anche perchè poi il programma è finito):
dopo che l'applicazione ha copiato i file deve anche chiudere la finestra che visualizzava l'avanzamento, allora ho scritto questo che però chiudeva l'applicazione intera ma non va:

SendMessage(g_hToolbar, WM_CLOSE, NULL, NULL);

cosa devo cambiare???

DanieleC88
21-08-2008, 21:00
Non è una toolbar quella, a vedere dal nome? :wtf:
Probabilmente propaga il messaggio alla finestra genitrice, ma la sto sparando. Non c'era una funzione come CloseWindow() o ricordo male?

71104
21-08-2008, 21:23
Non è una toolbar quella, a vedere dal nome? :wtf:
Probabilmente propaga il messaggio alla finestra genitrice, ma la sto sparando. Non c'era una funzione come CloseWindow() o ricordo male?
le toolbar propagano solo i WM_COMMAND. la CloseWindow esiste, ma non fa quello che suggerisce il nome: la finestra resta perfettamente aperta, viene solo minimizzata. http://msdn.microsoft.com/en-us/library/ms632678.aspx

inviare WM_CLOSE e chiamare CloseWindow sono due cose diverse. tra l'altro non penso che lui debba chiudere (cioè invisibilizzare) la finestra, ma che debba proprio distruggerla, e in tal caso la procedura varia a seconda del tipo di finestra (main window, modal dialog, modeless dialog).

DanieleC88
21-08-2008, 21:35
Devo decisamente ripassarmi le API Win32, non mi ricordo più un granché... :D

Mattyfog
21-08-2008, 21:40
Ciao,

giustamente come intuito io vorrei distruggere la finestra.
Si tratta di una modeless dialog.
Come posso fare?

71104
21-08-2008, 21:42
Ciao,

giustamente come intuito io vorrei distruggere la finestra.
Si tratta di una modeless dialog.
Come posso fare?
come da MSDN, le modeless si distruggono allo stesso modo delle finestre normali; devi chiamare DestroyWindow.

Mattyfog
21-08-2008, 22:29
scrivendo questo:

DestroyWindow(g_hToolbar);

si verifica lo stesso errore di prima ossia si esce completamente dal programma.

Mattyfog
22-08-2008, 13:08
please help me!!!
non che mi senta abbandonato, anzi su questo forum mi date supporto continuo!!! grazie!!! solo che domani parto e vorrei finirlo... grazie ciao:)

DanieleC88
22-08-2008, 13:39
Ma g_hToolbar è l'handle di cosa, di preciso? Non posso dirti cosa stia succedendo nella tua applicazione, ma magari la window procedure che gestisce i messaggi reagisce terminando l'applicazione una volta inviato quel messaggio... posso solo ipotizzare. :D

Mattyfog
22-08-2008, 14:09
è l'handle di una modeless bar, quella che uso per visualizzare il progresso della copia.

DanieleC88
22-08-2008, 15:15
Che intendi per modeless bar? :wtf:

Mattyfog
22-08-2008, 15:33
scusa che stupido! intendevo modeless dialog!

DanieleC88
22-08-2008, 15:45
Be', se chiami DestroyWindow() sulla finestra figlia, non vedo come si possa chiudere la finestra genitrice, a meno che la figlia non lo faccia esplicitamente reagendo al messaggio di chiusura... :D

Posso vedere il codice intero, se non ti dispiace? Se è una cosa che preferisci non allegare completamente non fa niente. :)

71104
22-08-2008, 15:57
ma stai usando MFC? in tal caso è normale che il programma esca se hai impostato quella finestra come main window.

Mattyfog
22-08-2008, 17:38
non ci sarà bisogno del codice sorgente (cioè se proprio ti interessa, ma dubito fortemente!!!!! :D ) perchè adesso funziona.
Il punto è che nella Dialog procedure c'era un comando che in caso venisse chiamato detroywindow avrebbe chiuso il programma.
ciao e grazie infinite!!!

DanieleC88
22-08-2008, 18:00
Il punto è che nella Dialog procedure c'era un comando che in caso venisse chiamato detroywindow avrebbe chiuso il programma.
Sono un grande.
[...] magari la window procedure che gestisce i messaggi reagisce terminando l'applicazione una volta inviato quel messaggio...
:asd:

...Scherzo, ho avuto culo. :p
ciao ;)

Mattyfog
22-08-2008, 18:14
l'avevi detto anche tu???
ti giuro non l'avevo capito!!! :stordita:
che scemo che sono!!! scusa ciao

DanieleC88
22-08-2008, 18:17
L'avevo detto, sì, ma in effetti sono stato un po' troppo sibillino... mea culpa. :)

ciao ;)