Visualizzazione dei risultati da 1 a 7 su 7
  1. #1

    [C++] GUI con Win32 Aiuto

    Il seguente programma scrive "Prova prova prova prova" in colonna per 50 volte a intervalli di 200ms, però la scroll bar rimane sempre all'inizio, mentre vorrei che andasse giù insieme al testo.

    Ad esempio come avviene nelle finestre delle chat tipo msn o skype.

    Come dovrei fare? Grazie in anticipo

    Ecco il codice:
    codice:
    #include <windows.h>
    #include <string>
    #include <stdio.h>
    #include <conio.h>
    #include <stdlib.h>
    #define Show(Window) RedrawWindow(Window,0,0,0);ShowWindow(Window,SW_SHOW);
    using namespace std;
    
    MSG msg;
    HINSTANCE hInst;
    HWND form1,label21;
    
    int i=0;
    char buffer[50];
    
    void procedura_thread();
    void reg(UINT style,WNDPROC lpfnWndProc,int cbClsExtra,int cbWndExtra,HINSTANCE hInstance,HICON hIcon,HCURSOR hCursor,HBRUSH hbrBackground,LPCTSTR lpszMenuName,LPCTSTR lpszClassName);
    
    LRESULT CALLBACK WinProc (HWND, UINT, WPARAM, LPARAM);
    
    int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR lpCmdLine, int nCmdShow)
    {
    
        hInst = hInstance;
        reg(CS_HREDRAW | CS_VREDRAW | CS_OWNDC,WinProc,0,0,hInst,LoadIcon(NULL,IDI_WINLOGO),LoadCursor(NULL,IDC_ARROW),(HBRUSH)(COLOR_BTNFACE+1),NULL,"principale");
    
        form1 = CreateWindow("principale","Finestra",WS_MINIMIZEBOX | WS_SIZEBOX | WS_CAPTION | WS_MAXIMIZEBOX | WS_POPUP | WS_SYSMENU,600,300,600,440,NULL,(HMENU)NULL,hInst,NULL);
        label21 = CreateWindow("Edit","",WS_CHILD | ES_LEFT | WS_BORDER| WS_VSCROLL | WS_HSCROLL | WS_VISIBLE | ES_READONLY | EM_SCROLLCARET | ES_MULTILINE | ES_AUTOVSCROLL,1,1,583,403,form1,(HMENU)NULL,hInst,NULL);
                                 
        Show(form1);
        CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)&procedura_thread,NULL,0,NULL);
    	
        while(GetMessage(&msg,NULL,0,0))
        {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
        return msg.wParam;
    }
    
    LRESULT CALLBACK WinProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
    {
        if (msg==WM_DESTROY)
        {
        UnregisterClass("principale",hInst);
        PostQuitMessage(0);
        }   
    
        return DefWindowProc(hWnd, msg, wParam, lParam);
    }
    
    
    void procedura_thread()
    {
         char Text[50];
         char buff[5000];
         i=0;
         while(i<=50)
         {
          sprintf(Text,"Prova prova prova prova%c%c",0x0D,0x0A);
          strncat (buff, Text, 46);
          SetWindowText(label21,buff);
          Sleep(200);
          Show(form1);
          i++;
         }    
    }
    
    void reg(UINT style,WNDPROC lpfnWndProc,int cbClsExtra,int cbWndExtra,HINSTANCE hInstance,HICON hIcon,HCURSOR hCursor,HBRUSH hbrBackground,LPCTSTR lpszMenuName,LPCTSTR lpszClassName)
    {
        WNDCLASS wc;
        
        wc.style = style;
        wc.lpfnWndProc = lpfnWndProc;
        wc.cbClsExtra = cbClsExtra;
        wc.cbWndExtra = cbWndExtra;
        wc.hInstance = hInstance;
        wc.hIcon = hIcon;
        wc.hCursor = hCursor;
        wc.hbrBackground = hbrBackground;
        wc.lpszMenuName = lpszMenuName;
        wc.lpszClassName = lpszClassName;
        RegisterClass(&wc);
    }

  2. #2
    Utente di HTML.it L'avatar di oregon
    Registrato dal
    Jul 2005
    residenza
    Roma
    Messaggi
    36,480
    Io aggiungerei l'header

    #include <windowsx.h>

    e modificherei questa funzione così

    codice:
    void procedura_thread()
    {
        char Text[50];
        char buff[5000] = {0};
        i=0;
    
        while(i<50)
        {
            sprintf(Text,"%d Prova prova prova prova\r\n", i+1);
            strncat (buff, Text, 46);
            SetWindowText(label21, buff);
            Edit_Scroll(label21, Edit_GetLineCount(label21), 0);
            Sleep(200);
            Show(form1);
            i++;
         }    
    }
    No MP tecnici (non rispondo nemmeno!), usa il forum.

  3. #3
    Ok è perfetto! grazie mille

    ora vorrei aggiungere ancora altri due controlli ad esempio:

    mentre la scrollbar scende, se la riporto su dovrebbe mostrarmi il testo corrispondente, mentre ora continua a visualizzarmi sempre le ultime righe stampate.

    Inoltre vorrei anche fare in modo che se clicco con il mouse su un carattere il cursore deve rimanere fermo su di esso e così anche la scrollbar dovrebbe fermarsi, ad esempio gestirei con un if
    Edit_Scroll(label21, Edit_GetLineCount(label21), 0), ma non so come gestire vari eventi(spostamento del cursore su una determinata riga/colonna, oppure come faccio a spostare il cursore ad ogni ristampa?).

    Ora invece il cursore a ogni SetWindowText(label21, buff); Ritorna all’inizio dello scritto.

    Come potrei fare? Grazie in anticipo.

  4. #4
    Utente di HTML.it L'avatar di oregon
    Registrato dal
    Jul 2005
    residenza
    Roma
    Messaggi
    36,480
    Originariamente inviato da Stormlord1736
    mentre la scrollbar scende, se la riporto su dovrebbe mostrarmi il testo corrispondente, mentre ora continua a visualizzarmi sempre le ultime righe stampate.
    Che vuol dire? Mentre scende significa che il loop è in esecuzione e quindi viene aggiunto la prossima linea all'ultimo e visualizzata ... ovvio che visualizza sempre le ultime righe ... era quello che volevi ...

    Inoltre vorrei anche fare in modo che se clicco con il mouse su un carattere il cursore deve rimanere fermo su di esso e così anche la scrollbar dovrebbe fermarsi, ad esempio gestirei con un if ...
    Non ho capito quello che vuoi fare ma, se hai un ciclo come quello che hai mostrato, allora dovrai intervenire sul ciclo stesso per fermarlo ...
    No MP tecnici (non rispondo nemmeno!), usa il forum.

  5. #5
    Cerco di spiegare meglio riferendomi magari al comportamento di chat come msn o skype che magari rende meglio l'idea.

    Ad esempio su msn quando qualcuno scrive un messaggio la scrollbar scende giù insieme al testo ed è quello che ora il programma fa però, se ad esempio sempre su msn voglio rileggere quello che mi hanno scritto precedentemente allora salgo su con la scrollbar e anche se continuano ad arrivare nuovi messaggi istantanei la scrollbar non scorre più insieme al testo ma rimane ferma a visualizzare i messaggi precedenti.

    In poche parole vorrei una finestra che si comporti esattamente come quella di msn, così anche se seleziono del testo oppure posiziono il cursore su una lettera, questi non devono variare o ogni ristampa, spero di essere stato un po più chiaro.

    Grazie in anticipo

  6. #6
    codice:
    EM_CANUNDO
    EM_CHARFROMPOS
    EM_EMPTYUNDOBUFFER
    EM_FMTLINES
    EM_GETCUEBANNER
    EM_GETFIRSTVISIBLELINE
    EM_GETHANDLE
    EM_GETHILITE
    EM_GETIMESTATUS
    EM_GETLIMITTEXT
    EM_GETLINE
    EM_GETLINECOUNT
    EM_GETMARGINS
    EM_GETMODIFY
    EM_GETPASSWORDCHAR
    EM_GETRECT
    EM_GETSEL
    EM_GETTHUMB
    EM_GETWORDBREAKPROC
    EM_HIDEBALLOONTIP
    EM_LIMITTEXT
    EM_LINEFROMCHAR
    EM_LINEINDEX
    EM_LINELENGTH
    EM_LINESCROLL
    EM_NOSETFOCUS
    EM_POSFROMCHAR
    EM_REPLACESEL
    EM_SCROLL
    EM_SCROLLCARET
    EM_SETCUEBANNER
    EM_SETHANDLE
    EM_SETHILITE
    EM_SETIMESTATUS
    EM_SETLIMITTEXT
    EM_SETMARGINS
    EM_SETMODIFY
    EM_SETPASSWORDCHAR
    EM_SETREADONLY
    EM_SETRECTEM_SETRECT
    EM_SETRECTNP
    EM_SETSEL
    EM_SETTABSTOPS
    EM_SETWORDBREAKPROC
    EM_SHOWBALLOONTIP
    EM_TAKEFOCUS
    EM_UNDO
    WM_UNDO
    Questi sono tutti i messaggi che posso utilizzare per vari controlli sugli edit, ma non sono proprio riuscito a trovare quello che fa per me.

    Avrei la necessità di sapere se la scroll bar viene spostata manualmente dell'utente, ho provato quindi con EM_GETTHUMB (non so se sia il messaggio corretto) ma ritorna sempre 0.

    Poi ho utilizzato anche EM_GETSEL e EM_SETSEL, per fare in modo che se l'utente seleziona del testo, questo deve rimanere selezionato anche dopo che l'edit viene ristampato con il testo agiuntivo.

    Dopo svariati tentativi non sono riuscito ad ottenere nulla.
    Il risultato che voglio ottenere è proprio quello di creare un edit che si comporti come una finestra di conversazione di messenger dove i messaggi istantanei sono la stringa "Prova prova prova".

    Come posso fare? Grazie in anticipo

  7. #7
    Alla fine ho risolto con una cosa di questo tipo (in caso dovesse servire a qualcuno):

    codice:
    #include <windows.h>
    #include <string>
    #include <stdio.h>
    #include <conio.h>
    #include <stdlib.h>
    #include <algorithm>
    
    using namespace std;
    
    MSG msg;
    HINSTANCE hInst;
    HWND form1,scroll1,label21;
    SCROLLINFO  si ;
    
    
    char buffer[50];
    char buff[5000] = {0};
    char buf[70][70];
    int nLineMax=0;
    bool yTrack=true;
    
    void procedura_thread();
    void reg(UINT style,WNDPROC lpfnWndProc,int cbClsExtra,int cbWndExtra,HINSTANCE hInstance,HICON hIcon,HCURSOR hCursor,HBRUSH hbrBackground,LPCTSTR lpszMenuName,LPCTSTR lpszClassName);
    
    LRESULT CALLBACK WinProc (HWND, UINT, WPARAM, LPARAM);
    
    int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR lpCmdLine, int nCmdShow)
    {
    
        hInst = hInstance;
        reg(CS_HREDRAW | CS_VREDRAW | CS_OWNDC,WinProc,0,0,hInst,LoadIcon(NULL,IDI_WINLOGO),LoadCursor(NULL,IDC_ARROW),(HBRUSH)(COLOR_BTNFACE+0),NULL,"principale");
    
        form1   = CreateWindow("principale","Finestra",WS_MINIMIZEBOX | WS_SIZEBOX | WS_CAPTION | WS_MAXIMIZEBOX | WS_POPUP | WS_SYSMENU,600,300,600,440,NULL,(HMENU)NULL,hInst,NULL);
        //label21 = CreateWindow("Edit","",WS_CHILD | ES_LEFT | WS_BORDER | WS_VISIBLE | ES_READONLY | ES_MULTILINE | WS_VSCROLL,1,1,583,203,form1,(HMENU)NULL,hInst,NULL);
                                 
        ShowWindow(form1,SW_SHOWNORMAL);
        UpdateWindow(form1);
        CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)&procedura_thread,NULL,0,NULL);
    	
        while(GetMessage(&msg,NULL,0,0))
        {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
        return msg.wParam;
    }
    
    LRESULT CALLBACK WinProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
    {
         static int  cxChar, cxCaps, cyChar, cxClient, cyClient, iMaxWidth;
         HDC         hdc ;
         int         i, x, y, iVertPos, iHorzPos, iPaintBeg, iPaintEnd;
         PAINTSTRUCT ps ;
         TEXTMETRIC  tm ;
         
         switch (message)
         {
         case WM_CREATE:
              hdc = GetDC (hwnd) ;
              
              GetTextMetrics (hdc, &tm) ;
              cxChar = tm.tmAveCharWidth ;
              cxCaps = (tm.tmPitchAndFamily & 1 ? 3 : 2) * cxChar / 2 ;
              cyChar = tm.tmHeight + tm.tmExternalLeading ;
              
              si.cbSize = sizeof (si) ;
              si.fMask  = SIF_RANGE;
              si.nMin   = 0 ;
              si.nMax   = nLineMax ;
              SetScrollInfo (hwnd, SB_VERT, &si, TRUE) ;
              
              si.cbSize = sizeof (si) ;
              si.fMask  = SIF_RANGE;
              si.nMin   = 0 ;
              si.nMax   = 2 + iMaxWidth / cxChar ;
              SetScrollInfo (hwnd, SB_HORZ, &si, TRUE) ;
              
              ReleaseDC (hwnd, hdc) ;
    
                   // Save the width of the three columns
              
              iMaxWidth = 40 * cxChar + 22 * cxCaps ;
               break ;
              
         case WM_SIZE:
              cxClient = LOWORD (lParam) ;
              cyClient = HIWORD (lParam) ;
    
                   // Set vertical scroll bar range and page size
    
              si.cbSize = sizeof (si) ;
              si.fMask  = SIF_PAGE ;
              si.nPage  = cyClient / cyChar ;
              SetScrollInfo (hwnd, SB_VERT, &si, TRUE) ;
    
                   // Set horizontal scroll bar range and page size
    
              si.cbSize = sizeof (si) ;
              si.fMask  = SIF_PAGE ;
              si.nPage  = cxClient / cxChar ;
              SetScrollInfo (hwnd, SB_HORZ, &si, TRUE) ;
              break ;
              
         case WM_VSCROLL:
              si.cbSize = sizeof (si) ;
              si.fMask  = SIF_ALL ;
              GetScrollInfo (hwnd, SB_VERT, &si) ;
              
              iVertPos = si.nPos ;
    
              switch (LOWORD (wParam))
              {
              case SB_TOP:
                   si.nPos = si.nMin ;
                   break;
                   
              case SB_BOTTOM:
                   si.nPos = si.nMax ;
                   break;
                   
              case SB_LINEUP:
                   si.nPos -= 1 ;
                   break ;
                   
              case SB_LINEDOWN:
                   si.nPos += 1 ;
                   break ;
                   
              case SB_PAGEUP:
                   si.nPos -= si.nPage ;
                   break ;
                   
              case SB_PAGEDOWN:
                   si.nPos += si.nPage ;
                   break ;
                          
              case SB_THUMBTRACK:
                   si.nPos = si.nTrackPos;
                   break ;
                   
              default:
                   break ;         
              }
    
              si.fMask = SIF_ALL;
              SetScrollInfo (hwnd, SB_VERT, &si, TRUE) ;
              GetScrollInfo (hwnd, SB_VERT, &si) ;
              if (si.nPos==(si.nMax-si.nPage)+1){yTrack=true;}else{yTrack=false;}
    
              if (si.nPos != iVertPos)
              {                 
                   ScrollWindow (hwnd, 0, cyChar * (iVertPos - si.nPos), NULL, NULL) ;
                   UpdateWindow (hwnd) ;
              }
              break ;
              
         case WM_HSCROLL:
              si.cbSize = sizeof (si) ;
              si.fMask  = SIF_ALL ;
              GetScrollInfo (hwnd, SB_HORZ, &si) ;
             
              iHorzPos = si.nPos ;
    
              switch (LOWORD (wParam))
              {
              case SB_LINELEFT:
                   si.nPos -= 1 ;
                   break ;
                   
              case SB_LINERIGHT:
                   si.nPos += 1 ;
                   break ;
                   
              case SB_PAGELEFT:
                   si.nPos -= si.nPage ;
                   break ;
                   
              case SB_PAGERIGHT:
                   si.nPos += si.nPage ;
                   break ;
                   
              case SB_THUMBPOSITION:
                   si.nPos = si.nTrackPos ;
                   break ;
                   
              default :
                   break ;
              }
    
              si.fMask = SIF_POS ;
              SetScrollInfo (hwnd, SB_HORZ, &si, TRUE) ;
              GetScrollInfo (hwnd, SB_HORZ, &si) ;
              
                   // If the position has changed, scroll the window 
    
              if (si.nPos != iHorzPos)
              {
                   ScrollWindow (hwnd, cxChar * (iHorzPos - si.nPos), 0, NULL, NULL) ;
                   UpdateWindow(hwnd);
              }
              break ;
    
         case WM_PAINT :
              hdc = BeginPaint (hwnd, &ps) ;
    
              // Get vertical scroll bar position
    
              si.cbSize = sizeof (si) ;
              si.fMask  = SIF_POS ;
              GetScrollInfo (hwnd, SB_VERT, &si) ;
              iVertPos = si.nPos ;
    
                   // Get horizontal scroll bar position
    
              GetScrollInfo (hwnd, SB_HORZ, &si) ;
              iHorzPos = si.nPos ;
    
                   // Find painting limits
    
              iPaintBeg = max (0, (int)(iVertPos + ps.rcPaint.top / cyChar)) ;
              iPaintEnd = min (nLineMax,(int)(iVertPos + ps.rcPaint.bottom / cyChar)) ;
              
              for (i = iPaintBeg ; i <= iPaintEnd ; i++)
              {
                   x = cxChar * (1 - iHorzPos) ;
                   y = cyChar * (i - iVertPos) ;
                   
                   TextOut (hdc, 0, y,buf[i],lstrlen (buf[i])) ;
    
              }
    
              EndPaint (hwnd, &ps) ;
              break ;
              
         case WM_DESTROY :
              PostQuitMessage (0) ;
              break ;
         }
         return DefWindowProc (hwnd, message, wParam, lParam) ;
    }
    
    
    
    
    
    void procedura_thread()
    {
        char Text[50];
    
        while(nLineMax<60)
        {
            SetScrollRange(form1, SB_VERT, 0, nLineMax,FALSE);
            si.fMask  = SIF_ALL;
            GetScrollInfo (form1, SB_VERT, &si);
    
            if (yTrack){SetScrollPos(form1, SB_VERT, (si.nMax-si.nPage)+1,FALSE);}
    
            SendMessage(form1,WM_SIZE,0,0);
            UpdateWindow(form1);
            
            sprintf(Text,"%d Prova purova prova prova", nLineMax);
            strcpy(buf[nLineMax],Text);
            Sleep(700);
            nLineMax++;
         }     
    }
    
    
    void reg(UINT style,WNDPROC lpfnWndProc,int cbClsExtra,int cbWndExtra,HINSTANCE hInstance,HICON hIcon,HCURSOR hCursor,HBRUSH hbrBackground,LPCTSTR lpszMenuName,LPCTSTR lpszClassName)
    {
        WNDCLASS wc;
        
        wc.style = style;
        wc.lpfnWndProc = lpfnWndProc;
        wc.cbClsExtra = cbClsExtra;
        wc.cbWndExtra = cbWndExtra;
        wc.hInstance = hInstance;
        wc.hIcon = hIcon;
        wc.hCursor = hCursor;
        wc.hbrBackground = hbrBackground;
        wc.lpszMenuName = lpszMenuName;
        wc.lpszClassName = lpszClassName;
        RegisterClass(&wc);
    }

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2025 vBulletin Solutions, Inc. All rights reserved.