WxWidgets : Frame e Window

di il
31 risposte

31 Risposte - Pagina 2

  • Re: WxWidgets : Frame e Window

    @Rubik come hai fatto per trasmettere in una finestra tanto codice scrollabile ?
    @Unoqualunque , ma allora dove é il divertimento ? Se dovessi mantenere lo stesso programma scritto 40 anni fa sarebbe una clamorosa affermazione di fallimento intellettivo. Naturalmente quel programma lo scriverei in modo totalmente diverso, credo di gran lunga più efficiente e compatto , anche se già allora era molto più compatto di programmi comparabili . Solo vorrei introdurre la gestione degli eventi , un tocco di risoluzione grafica e .... qualche idea pazza . Come detto in più occasioni , non devo creare niente di commerciabile , solo la gratificazione di aver trasformato idee in qualcosa di funzionante e ... possibilmente migliore di quanto propone il mercato . ( tiè ! )
  • Re: WxWidgets : Frame e Window

    Unqualunque ha scritto:


    Rubik ha scritto:


    con il C o la vecchia scuola hai un flusso ininterrotto del codice che scorre impietosamente, o si è fermi in un input, o si sta eseguendo un ciclo.
    Ma chi l'ha detto? Questo può capitare finché non si sa come organizzare un codice complesso.
    L'ho detto io che non so organizzare un codice complesso in C.

    Unqualunque ha scritto:


    In C è molto facile creare un codice orientato agli eventi, anche se non è un linguaggio esplicitamente orientato agli eventi. Meno semplice invece è creare un codice orientato agli oggetti, ma volendo si può fare comunque, costruendo tutto quanto in modo esplicito.
    In C si può scrivere un sistema operativo, ma non significa che "volendo" lo possa scrivere io e neanche tu.

    Unqualunque ha scritto:


    Quello che fanno altri linguaggi più evoluti è automatizzare queste operazioni, ma inevitabilmente per farlo nascondono parte del codice mentre il programmatore non sa cosa si muove "sotto il cofano".
    Esatto invece di scervellarti inutilmente a gestire gli eventi, il sistema operativo lo fa per te, lasciandoti concentrato su questioni riguardanti il software che stai sviluppando.
  • Re: WxWidgets : Frame e Window

    Le librerie ti permettono di farlo in C++ allo stesso modo di come lo faresti in linguaggi più evoluti.

    @Rosamarino, seleziona il codice e premi il pulsante </> per aggiungere il tag.
  • Re: WxWidgets : Frame e Window

    Rosmarino ha scritto:


    @Rubik come hai fatto per trasmettere in una finestra tanto codice scrollabile ?
    Come ti ha già detto Alexv c'è il tastino code [</>]
    ___________________v
    code.png
    code.png

    se non lo vedi è perché prima devi scegliere: Editor completo & Anteprima:
    editor.png
    editor.png

    Tornando a noi, sappiamo che ci sono una miriade di possibilità per creare una GUI in C/C++, quello che non so è quale scegliere per iniziare, senza dover installare IDE sterminati perché fanno 1 milione di cose, o procedere con la programmazione spicciola.

    Per intenderci, ho già sperimentato solo per curiosità windows.h, codice mio:
    
    #include <windows.h>
    #include <math.h>
    
    #define DIM_SQUARE_W 840 // your chose
    #define DIM_SQUARE_H 576 // your chose
    #define POS_SQUARE 50    // your chose
    
    static HWND sHwnd;
    static COLORREF red=RGB(255,0,0);
    static COLORREF blue=RGB(0,0,255);
    static COLORREF green=RGB(0,255,0);
    static COLORREF black=RGB(0,0,0);
    
    void SetWindowHandle(HWND hwnd){
        sHwnd=hwnd;
    }
    
    void setPixel(int x, int y, COLORREF& color=black){ // black, if omitted
        if(sHwnd==NULL){
            MessageBox(NULL, "sHwnd was not initialized !", "Error", MB_OK|MB_ICONERROR);
            exit(0);
        }
        HDC hdc=GetDC(sHwnd);
        SetPixel(hdc, x, y, color);
        ReleaseDC(sHwnd, hdc);
        return;
    }
    
    void drawSin(){
        double y=0;
        for (double x=POS_SQUARE; x<DIM_SQUARE_W+POS_SQUARE; x++)
        {
            y=sin(x/50)*DIM_SQUARE_H/2; // y/50: frequency, DIM_SQUARE_H/2: max height
            setPixel((int)x,(int)y+DIM_SQUARE_H/2+POS_SQUARE, black); // DIM_SQUARE_H/2 centered
        }
    }
    
    void drawLine(){
        for(int w = 1; w <DIM_SQUARE_W; w++){
            setPixel(POS_SQUARE+w, POS_SQUARE, blue);
            setPixel(POS_SQUARE+w, POS_SQUARE+DIM_SQUARE_H, blue);
        }
        for(int h = 1; h <DIM_SQUARE_H; h++){
            setPixel(POS_SQUARE, POS_SQUARE+h, red);
            setPixel(POS_SQUARE+DIM_SQUARE_W, POS_SQUARE+h, red);
        }
    }
    
    LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam){
        switch(message){
        case WM_PAINT:
            SetWindowHandle(hwnd);
            drawLine(); // graphics routine
            drawSin();  // graphics routine
            break;
        case WM_CLOSE: // Failure to call DefWindowProc
            break;
        case WM_DESTROY:
            PostQuitMessage(0);
            return 0;
        default:
            break; // Failure to call DefWindowProc
        }
        return DefWindowProc(hwnd, message, wParam, lParam);
    }
    
    int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance, LPSTR lpCmdLine, int iCmdShow){
        static TCHAR szAppName[] = TEXT("Graphic");
        WNDCLASS wndclass;
        wndclass.style         = CS_HREDRAW|CS_VREDRAW ;
        wndclass.lpfnWndProc   = WndProc ;
        wndclass.cbClsExtra    = 0 ;
        wndclass.cbWndExtra    = 0 ;
        wndclass.hInstance     = hInstance ;
        wndclass.hIcon         = LoadIcon (NULL, IDI_APPLICATION) ;
        wndclass.hCursor       = LoadCursor (NULL, IDC_ARROW) ;
        wndclass.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH) ;
        wndclass.lpszMenuName  = NULL ;
        wndclass.lpszClassName = szAppName ;
    
        // Register the window
        if(!RegisterClass(& wndclass)){
            MessageBox(NULL, "Registering the class failed","Error", MB_OK|MB_ICONERROR);
            exit(0);
        }
    
        // CreateWindow
        HWND hwnd=CreateWindow(szAppName, "Graphic surface",
                               WS_OVERLAPPEDWINDOW,
                               CW_USEDEFAULT,
                               CW_USEDEFAULT,
                               CW_USEDEFAULT,
                               CW_USEDEFAULT,
                               NULL,
                               NULL,
                               hInstance,
                               NULL);
        if(!hwnd){
            MessageBox(NULL, "Window Creation Failed!","Error", MB_OK);
            exit(0);
        }
    
        // ShowWindow and UpdateWindow
        ShowWindow(hwnd, iCmdShow);
        UpdateWindow(hwnd);
    
        // Message Loop
        MSG msg;
        while(GetMessage(& msg, NULL,0,0)){
            TranslateMessage(& msg);
            DispatchMessage(& msg);
        }
        return 0;
    }
    
    oppure sempre tanto per vedere i common control, codice di Napalm:
    
    //
    // Log Window Test App - by Napalm
    //
    // You may use all or any part of the following code as long as you agree
    // to the Creative Commons Attribution 2.0 UK: England & Wales license.
    // [url="http://creativecommons.org/licenses/by/2.0/uk/"]http://creativecommo...nses/by/2.0/uk/[/url]
    //
    // You must have the up to date headers to compile this.. if you can't
    // compile it install the PSDK/Windows SDK and try again.
    //
    //
    #define _WIN32_WINNT            0x0501
    #include <windows.h>
    #include <commctrl.h>
    #include <shlwapi.h>
    
    #define LOG_LINE_LIMIT          25
    
    // Child Window/Control IDs
    #define IDC_TXTENTRY            100
    #define IDC_TXTLOG              101
    #define IDC_BTNADDENTRY         102
    #define IDC_CHKPINTOBOTTOM      103
    #define IDC_CHKLIMITBUFFER      104
    
    // Globals
    HINSTANCE g_hInst;
    HFONT g_hfText;
    
    // I created this to change the default properties of how edit controls behave
    // when accessed by the dialog manager.
    LRESULT CALLBACK SubclassEditProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
    {
        WNDPROC wpOld = (WNDPROC)GetWindowLongPtr(hWnd, GWLP_USERDATA);
        LRESULT lrResult = 0;
    
        if(wpOld){
            switch(uMsg)
            {
                // Draw fancy gradient background in log edit control
                case WM_ERASEBKGND:
                    {
                        RECT rc;
                        if(GetClientRect(hWnd, &rc)){
                            INT nW  = (rc.right - rc.left);
                            INT nH  = (rc.bottom - rc.top);
                            TRIVERTEX triVertex[5] = {
                                {  0, nH,    0xFF00, 0xFF00, 0xFF00, 0x0000 },
                                { nW, nH / 2, 0xFF00, 0xFF00, 0xFF00, 0x0000 },
                                { nW, nH,    0xBB00, 0xDD00, 0xF700, 0x0000 },
                            };
                            GRADIENT_TRIANGLE triMesh = { 0, 1, 2 };
                            HDC hdc = (HDC)wParam;
                            INT ndc = SaveDC(hdc);
                            SetBkColor(hdc, RGB(255, 255, 255));
                            ExtTextOut(hdc, 0, 0, ETO_OPAQUE, &rc, NULL, 0, NULL);
                            // GradientFill(hdc, triVertex, 3, &triMesh, 1, GRADIENT_FILL_TRIANGLE);
                            RestoreDC(hdc, ndc);
                            return 0;
                        }
                    }
                    break;
    
                // Last message to a window so we de-subclass ourselves.
                case WM_NCDESTROY:
                    SetWindowLongPtr(hWnd, GWLP_WNDPROC, (LONG_PTR)wpOld);
                    SetWindowLongPtr(hWnd, GWLP_USERDATA, 0);
                    break;
    
                // Sent by IsDialogMessage() API to determine what keys the control wants.
                // We use this to forward the tab key so it selects the next control.
                case WM_GETDLGCODE:
                    lrResult = CallWindowProc(wpOld, hWnd, uMsg, wParam, lParam);
                    lrResult &= ~(DLGC_HASSETSEL | DLGC_WANTTAB);
                    if(lParam && ((LPMSG)lParam)->message == WM_KEYDOWN &&
                        ((LPMSG)lParam)->wParam == VK_TAB)
                        lrResult &= ~DLGC_WANTMESSAGE;
                    return lrResult;
            }
    
            // Call the original window procedure.
            return CallWindowProc(wpOld, hWnd, uMsg, wParam, lParam);
        }
    
        // Crap couldn't find the original window procedure... use default.
        return DefWindowProc(hWnd, uMsg, wParam, lParam);
    }
    
    LRESULT CALLBACK MainWindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
    {
        // We should not have used a static.. we should really attach this value to the window
        // using either GWL_USERDATA or a allocated structure with a a pointer stored in GWL_USERDATA.
        static HWND s_hWndLastFocus;
    
        switch(uMsg)
        {
            // Initialize our window and create our child controls.
            case WM_CREATE:
                {
                    HWND hWndChild;
                    TCHAR szBuffer[MAX_PATH];
    
                    // TEXT("This text will be appended to the box below.")
                    // Create the 'entry box' single-line edit control.
                    hWndChild = CreateWindowEx(WS_EX_CLIENTEDGE, WC_EDIT, NULL,
                        ES_AUTOHSCROLL | WS_CHILD | WS_TABSTOP | WS_VISIBLE,
                        0, 0, 0, 0, hWnd, (HMENU)IDC_TXTENTRY, g_hInst, NULL);
                    if(!hWndChild) return -1;
                    // Subclass the edit control.
                    SetWindowLongPtr(hWndChild, GWLP_USERDATA, GetWindowLongPtr(hWndChild, GWLP_WNDPROC));
                    SetWindowLongPtr(hWndChild, GWLP_WNDPROC, (LONG_PTR)SubclassEditProc);
                    // Set the edit controls properties.
                    SendMessage(hWndChild, WM_SETFONT, (WPARAM)g_hfText, FALSE);
                    SendMessage(hWndChild, EM_SETMARGINS, EC_LEFTMARGIN | EC_RIGHTMARGIN, 0);
                    // SendMessage(hWndChild, EM_SETCUEBANNER, 0, (LPARAM)TEXT("Log Entry Text"));
    
                    // Create the 'add entry' button.
                    hWndChild = CreateWindowEx(0, WC_BUTTON, TEXT("&Add Entry"),
                        BS_PUSHBUTTON | BS_TEXT |
                        WS_CHILD | WS_TABSTOP | WS_VISIBLE,
                        0, 0, 0, 0, hWnd, (HMENU)IDC_BTNADDENTRY, g_hInst, NULL);
                    if(!hWndChild) return -1;
                    // Set the button controls properties.
                    SendMessage(hWndChild, WM_SETFONT, (WPARAM)g_hfText, FALSE);
    
                    // Create first options check-box.
                    hWndChild = CreateWindowEx(0, WC_BUTTON, TEXT("Pin scroll to bottom."),
                        BS_CHECKBOX | BS_AUTOCHECKBOX | BS_TEXT | BS_VCENTER |
                        WS_CHILD | WS_TABSTOP | WS_VISIBLE,
                        0, 0, 0, 0, hWnd, (HMENU)IDC_CHKPINTOBOTTOM, g_hInst, NULL);
                    if(!hWndChild) return -1;
                    // Set the button controls properties.
                    SendMessage(hWndChild, WM_SETFONT, (WPARAM)g_hfText, FALSE);
                    SendMessage(hWndChild, BM_SETCHECK, BST_CHECKED, 0);
    
                    // Create second options check-box.
                    wsprintf(szBuffer, TEXT("Limit log to %u lines."), LOG_LINE_LIMIT);
                    hWndChild = CreateWindowEx(0, WC_BUTTON, szBuffer,
                        BS_CHECKBOX | BS_AUTOCHECKBOX | BS_TEXT | BS_VCENTER |
                        WS_CHILD | WS_TABSTOP | WS_VISIBLE,
                        0, 0, 0, 0, hWnd, (HMENU)IDC_CHKLIMITBUFFER, g_hInst, NULL);
                    if(!hWndChild) return -1;
                    // Set the button controls properties.
                    SendMessage(hWndChild, WM_SETFONT, (WPARAM)g_hfText, FALSE);
                    SendMessage(hWndChild, BM_SETCHECK, BST_CHECKED, 0);
    
                    // Create 'log window' multi-line edit control.
                    hWndChild = CreateWindowEx(WS_EX_CLIENTEDGE, WC_EDIT, NULL,
                        ES_MULTILINE | ES_WANTRETURN | ES_AUTOVSCROLL | ES_NOHIDESEL |
                        WS_VSCROLL | WS_CHILD | WS_TABSTOP | WS_VISIBLE,
                        0, 0, 0, 0, hWnd, (HMENU)IDC_TXTLOG, g_hInst, NULL);
                    if(!hWndChild) return -1;
                    // Subclass the edit control.
                    SetWindowLongPtr(hWndChild, GWLP_USERDATA, GetWindowLongPtr(hWndChild, GWLP_WNDPROC));
                    SetWindowLongPtr(hWndChild, GWLP_WNDPROC, (LONG_PTR)SubclassEditProc);
                    // Set the edit controls properties.
                    SendMessage(hWndChild, WM_SETFONT, (WPARAM)g_hfText, FALSE);
                    SendMessage(hWndChild, EM_SETMARGINS, EC_LEFTMARGIN | EC_RIGHTMARGIN, 0);
    
                    SetFocus(hWndChild);
                    s_hWndLastFocus = NULL;
                }
                return 0;
    
            // We get this message with WA_INACTIVE set when our window is no-longer
            // the foreground window so we want to save which of our controls has the focus
            // so that when the user returns the right control gets the keyboard input.
            case WM_ACTIVATE:
                if(LOWORD(wParam) == WA_INACTIVE)
                    s_hWndLastFocus = GetFocus();
                return 0;
    
            // We get this message when our window receives the user focus. We then
            // move that focus to the previously used child window.
            case WM_SETFOCUS:
                if(s_hWndLastFocus)
                    SetFocus(s_hWndLastFocus);
                return 0;
    
            // We accept this message so we can set a minimum window size. This only sets the users
            // tracking size. The window itself can always be resized smaller programmatically unless
            // you restrict it in WM_WINDOWPOSCHANGING/WM_WINDOWPOSCHANGED.
            case WM_GETMINMAXINFO:
                {
                    LPMINMAXINFO lpInfo = (LPMINMAXINFO)lParam;
                    if(lpInfo)
                        lpInfo->ptMinTrackSize.x = 350, lpInfo->ptMinTrackSize.y = 280;
                }
                return 0;
    
            // These next two messages are better to use rather than WM_MOVE/WM_SIZE.
            // Remember WM_MOVE/WM_SIZE are from 16bit windows. In 32bit windows the window
            // manager only sends these two messages and the DefWindowProc() handler actually
            // accepts them and converts them to WM_MOVE/WM_SIZE.
            //
            // We accept this so we can scale our controls to the client size.
            case WM_WINDOWPOSCHANGING:
            case WM_WINDOWPOSCHANGED:
                {
                    HDWP hDWP;
                    RECT rc;
    
                    // Create a deferred window handle.
                    if(hDWP = BeginDeferWindowPos(5)){ // Deferring 5 child controls
                        GetClientRect(hWnd, &rc);
    
                        // Defer each window move/size until end and do them all at once.
                        hDWP = DeferWindowPos(hDWP, GetDlgItem(hWnd, IDC_TXTENTRY), NULL,
                            10, 10, rc.right - 130, 25,
                            SWP_NOZORDER | SWP_NOREDRAW);
    
                        hDWP = DeferWindowPos(hDWP, GetDlgItem(hWnd, IDC_BTNADDENTRY), NULL,
                            rc.right - 110, 10, 100, 25,
                            SWP_NOZORDER | SWP_NOREDRAW);
    
                        hDWP = DeferWindowPos(hDWP, GetDlgItem(hWnd, IDC_CHKPINTOBOTTOM), NULL,
                            10, 35, (rc.right / 2) - 15, 35,
                            SWP_NOZORDER | SWP_NOREDRAW);
    
                        hDWP = DeferWindowPos(hDWP, GetDlgItem(hWnd, IDC_CHKLIMITBUFFER), NULL,
                            (rc.right / 2) + 5, 35, (rc.right / 2) - 15, 35,
                            SWP_NOZORDER | SWP_NOREDRAW);
    
                        hDWP = DeferWindowPos(hDWP, GetDlgItem(hWnd, IDC_TXTLOG), NULL,
                            10, 70, rc.right - 20, rc.bottom - 80,
                            SWP_NOZORDER | SWP_NOREDRAW);
    
                        // Resize all windows under the deferred window handled at the same time.
                        EndDeferWindowPos(hDWP);
    
                        // We told DeferWindowPos not to redraw the controls so we can redraw
                        // them here all at once.
                        RedrawWindow(hWnd, NULL, NULL, RDW_INVALIDATE | RDW_ALLCHILDREN |
                            RDW_ERASE | RDW_NOFRAME | RDW_UPDATENOW);
                    }
                }
                return 0;
    
            // Handle the notifications of button presses.
            case WM_COMMAND:
                // If it was a button press and came from our button.
                if(wParam == MAKELONG(IDC_BTNADDENTRY, BN_CLICKED)){
    
                    UINT uChkPinToBottom, uChkLimitLogLength;
                    INT nSelStart, nSelEnd;
                    SCROLLINFO siLogVert;
                    HWND hWndChild;
                    LPTSTR lpBuffer;
                    INT cchTextLen;
    
                    // Allocate a buffer for our entry text.
                    // The +2 is for an extra space we append and null terminator.
                    hWndChild  = GetDlgItem(hWnd, IDC_TXTENTRY);
                    cchTextLen = GetWindowTextLength(hWndChild);
                    lpBuffer   = (LPTSTR)HeapAlloc(GetProcessHeap(),
                        HEAP_ZERO_MEMORY, (cchTextLen + 2) * sizeof(TCHAR));
                    if(lpBuffer == NULL){
                        // Fuck.. what happened???
                        MessageBeep(MB_ICONERROR);
                        return 0;
                    }
    
                    // Read our entry text.
                    if(GetWindowText(hWndChild, lpBuffer, cchTextLen + 1)){
                        StrCat(lpBuffer, TEXT(" "));
    
                        // Get the check-box states so we can change our logic depending on them.
                        uChkPinToBottom = (DWORD)SendDlgItemMessage(hWnd,
                            IDC_CHKPINTOBOTTOM, BM_GETCHECK, 0, 0);
                        uChkLimitLogLength = (DWORD)SendDlgItemMessage(hWnd,
                            IDC_CHKLIMITBUFFER, BM_GETCHECK, 0, 0);
    
                        // Get our edit log window handle.
                        hWndChild = GetDlgItem(hWnd, IDC_TXTLOG);
    
                        // Tell edit control not to update the screen.
                        SendMessage(hWndChild, WM_SETREDRAW, FALSE, 0);
    
                        // Save our current selection.
                        nSelStart = nSelEnd = 0;
                        SendMessage(hWndChild, EM_GETSEL, (WPARAM)&nSelStart, (LPARAM)&nSelEnd);
    
                        // Save our current scroll info.
                        ZeroMemory(&siLogVert, sizeof(SCROLLINFO));
                        siLogVert.cbSize = sizeof(SCROLLINFO);
                        siLogVert.fMask  = SIF_PAGE | SIF_POS | SIF_RANGE;
                        GetScrollInfo(hWndChild, SB_VERT, &siLogVert);
    
                        // Limit log to LOG_LINE_LIMIT lines.
                        if(uChkLimitLogLength == BST_CHECKED){
                            // Test if more than LOG_LINE_LIMIT.
                            INT nLines = (INT)SendMessage(hWndChild, EM_GETLINECOUNT, 0, 0);
                            if(nLines > LOG_LINE_LIMIT){
                                // Replace content to remove with nothing.
                                INT nRemove = (DWORD)SendMessage(hWndChild, EM_LINEINDEX,
                                    (WPARAM)(nLines - LOG_LINE_LIMIT), 0);
                                SendMessage(hWndChild, EM_SETSEL, 0, nRemove);
                                SendMessage(hWndChild, EM_REPLACESEL, FALSE, (LPARAM)"");
                                // Update old selection indexes.
                                // nSelStart = max(nSelStart - nRemove, 0);
                                // nSelEnd   = max(nSelEnd - nRemove, 0);
                            }
                        }
    
                        // Update the log window by appending text to it.
                        cchTextLen = GetWindowTextLength(hWndChild);
                        SendMessage(hWndChild, EM_SETSEL, cchTextLen, cchTextLen);
                        SendMessage(hWndChild, EM_REPLACESEL, FALSE, (LPARAM)lpBuffer);
    
                        // Update Pin-To-Bottom behavior.
                        if(uChkPinToBottom == BST_CHECKED){
                            // Only Pin-To-Bottom when the user is in the bottom page.
                            UINT uScrollLines = 1;
                            SystemParametersInfo(SPI_GETWHEELSCROLLLINES, 0, &uScrollLines, 0);
                            if(siLogVert.nPos > (INT)(siLogVert.nMax -
                                siLogVert.nPage - uScrollLines))
                                SendMessage(hWndChild, WM_VSCROLL, SB_BOTTOM, 0);
                        }else{
                            // Restore scroll position if not pinned.
                            SendMessage(hWndChild, WM_VSCROLL, MAKELONG(siLogVert.nPos,
                                SB_THUMBPOSITION), 0);
                        }
    
                        // Restore old text selection.
                        SendMessage(hWndChild, EM_SETSEL, nSelStart, nSelEnd);
    
                        // Update the state of the edit control on the screen.
                        SendMessage(hWndChild, WM_SETREDRAW, TRUE, 0);
                        UpdateWindow(hWndChild);
    
                    }else{
                        // No text in the entry box?
                        MessageBeep(MB_ICONWARNING);
                    }
    
                    // Free temporary entry box allocation.
                    HeapFree(GetProcessHeap(), 0, lpBuffer);
                    return 0;
                }
                break;
    
            // Sent by all edit controls that are not disabled.
            case WM_CTLCOLOREDIT:
                // Test to see if the request is from our log edit control.
                if((HWND)lParam == GetDlgItem(hWnd, IDC_TXTLOG)){
                    // Set the edit control painting of the background to transparent.
                    SetBkMode((HDC)wParam, TRANSPARENT);
                    SetTextColor((HDC)wParam, RGB(0x2B, 0x4C, 0x67));
                    return (LRESULT)GetStockObject(HOLLOW_BRUSH);
                }
                break;
    
            case WM_DESTROY:
                // We post a WM_QUIT when our window is destroyed so we break the main message loop.
                PostQuitMessage(0);
                break;
        }
    
        // Not a message we wanted? No problem hand it over to the Default Window Procedure.
        return DefWindowProc(hWnd, uMsg, wParam, lParam);
    }
    
    // Program Entry Point
    int APIENTRY WinMain(HINSTANCE hInst, HINSTANCE hPrev, LPSTR lpCmdLine, INT nShowCmd)
    {
        OSVERSIONINFO lpVer;
        WNDCLASSEX wcex;
        DWORD dwExStyle;
        HDC hdcScreen;
        HWND hWnd;
        MSG msg;
    
        g_hInst = hInst;
    
        // Link in comctl32.dll
        InitCommonControls();
    
        ZeroMemory(&msg,  sizeof(MSG));
        ZeroMemory(&wcex, sizeof(WNDCLASSEX));
    
        // Register our Main Window class.
        wcex.cbSize     = sizeof(WNDCLASSEX);
        wcex.hInstance   = hInst;
        wcex.lpszClassName = TEXT("MainWindow");
        wcex.lpfnWndProc   = MainWindowProc;
        wcex.hCursor       = LoadCursor(NULL, IDC_ARROW);
        wcex.hIcon       = LoadIcon(NULL, IDI_APPLICATION);
        wcex.hIconSm       = wcex.hIcon;
        wcex.hbrBackground = (HBRUSH)(COLOR_BTNFACE + 1);
        if(!RegisterClassEx(&wcex))
            return 1;
    
        // Create a font we can later use on our controls.
        hdcScreen = GetDC(HWND_DESKTOP);
        g_hfText = CreateFont(-MulDiv(11, GetDeviceCaps(hdcScreen, LOGPIXELSY), 72), // 11pt
            0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, ANSI_CHARSET, OUT_TT_PRECIS,
            CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, FF_DONTCARE, TEXT("Tahoma"));
        ReleaseDC(HWND_DESKTOP, hdcScreen);
    
        // Default main window ex-style.
        dwExStyle = WS_EX_APPWINDOW;
    
        // If we are using XP or above lets 'double-buffer' the window to reduce the
        // flicker to the edit controls when drawing (notepad needs this).
        lpVer.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
        if(GetVersionEx(&lpVer) && (lpVer.dwMajorVersion > 5 ||
            (lpVer.dwMajorVersion == 5 && lpVer.dwMinorVersion == 1)))
            dwExStyle |= WS_EX_COMPOSITED;
    
        // Create an instance of the Main Window.
        hWnd = CreateWindowEx(dwExStyle, wcex.lpszClassName, TEXT("Log Window Test App v2 - by Napalm"),
            WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN, CW_USEDEFAULT, CW_USEDEFAULT, 450, 330,
            HWND_DESKTOP, NULL, hInst, NULL);
    
        if(hWnd){
            // Show the main window and enter the message loop.
            ShowWindow(hWnd, nShowCmd);
            UpdateWindow(hWnd);
            while(GetMessage(&msg, NULL, 0, 0))
            {
                // If the message was not wanted by the Dialog Manager dispatch it like normal.
                if(!IsDialogMessage(hWnd, &msg)){
                    TranslateMessage(&msg);
                    DispatchMessage(&msg);
                }
            }
        }
    
        // Free up our resources and return.
        DeleteObject(g_hfText);
        return (int)msg.wParam;
    }
    
    Non voglio scoraggiarti Rosmarino ma devi decidere se vuoi scrivere il tuo gestionale o se vuoi imparare a scrivere un'interfaccia grafica in C++.

    Speriamo che Alexv, ci dia lumi, perché anche se troviamo una soluzione per l'interfaccia hai ancora il problema del linguaggio, il codice seguente per console in C#, scritto ora in 5 minuti, legge un file testo, questo:
    
    ID: ;NOME: ;COGNOME: ;DATA di nascita: ;RESIDENZA: ;;;
    04;Carlo;Ragaini;02/03/1989;Roma;
    02;Mario;Pagani;08/07/1990;Milano;
    08;Gianni;Luzi;12/06/1989;Palermo;
    01;Pino;Brusin;09/12/1991;Palermo;
    
    estrae la prima riga e la divide per definire i nomi dei campi, legge tutte le righe a mo di records e li mostra con i rispettivi nomi dei campi.
    finito il compito i record vengono riordinati e rimostrati in ordine.
    
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.IO;
    
    namespace ListSort
    {
        class Program
        {
            static void Main(string[] args)
            {
                List<string> TESTOletto = new List<string>(); // una lista di stringhe
                TESTOletto = File.ReadAllLines("CSVpuntoevirgola.txt").ToList(); // Carica in lista TESTOletto
                string[] campi =  TESTOletto[0].Split(';'); // definisce i nomi dei campi dividendo la prima riga
                TESTOletto.RemoveAt(0); // cancello dalla lista l'intestazione
                Visualizza(TESTOletto, campi);
                Console.WriteLine("------ ORDINATI -------");
                TESTOletto.Sort(); // ordinamento
                Visualizza(TESTOletto, campi);
            }
    
            static void Visualizza(List<string> records, string[] campi)
            {
                for (int i = 0; i < records.Count; i++) // tutti i record
                {
                    string[] rigaLetta = records[i].Split(';'); // in rigaLetta, le righe divise
                    for (int c = 0; c < campi.Count(); c++) // tutti i campi
                    {
                        Console.WriteLine(campi[c] + rigaLetta[c]); // visualizzazione
                    }
                }
            }
        }
    }
    
    Questo è l'output:
    
    ID: 04
    NOME: Carlo
    COGNOME: Ragaini
    DATA di nascita: 02/03/1989
    RESIDENZA: Roma
    
    ID: 02
    NOME: Mario
    COGNOME: Pagani
    DATA di nascita: 08/07/1990
    RESIDENZA: Milano
    
    ID: 08
    NOME: Gianni
    COGNOME: Luzi
    DATA di nascita: 12/06/1989
    RESIDENZA: Palermo
    
    ID: 01
    NOME: Pino
    COGNOME: Brusin
    DATA di nascita: 09/12/1991
    RESIDENZA: Palermo
    
    ------ ORDINATI -------
    ID: 01
    NOME: Pino
    COGNOME: Brusin
    DATA di nascita: 09/12/1991
    RESIDENZA: Palermo
    
    ID: 02
    NOME: Mario
    COGNOME: Pagani
    DATA di nascita: 08/07/1990
    RESIDENZA: Milano
    
    ID: 04
    NOME: Carlo
    COGNOME: Ragaini
    DATA di nascita: 02/03/1989
    RESIDENZA: Roma
    
    ID: 08
    NOME: Gianni
    COGNOME: Luzi
    DATA di nascita: 12/06/1989
    RESIDENZA: Palermo
    
    Premere un tasto per continuare . . .
    
    l'esempio è banale, ma comunque si adatta all'input, se aggiungi campi nell'intestazione o nuovi records li leggerà, prova a replicarlo in C, se l'esempio fosse più complicato il divario tra C# e C, si accentuerebbe.
    C'è anche il fatto che gli esempi per imparare che troverai in rete per il C per larga maggioranza non funzioneranno, perché saranno per un ambiente che non hai, usano una libreria che non hai, ha delle istruzioni per un compilatore diverso dal tuo, e da ultimo è per Linux. Più il tuo codice è avanzato e più quello che cerchi sarà sommerso da una valanga di codici inadeguati.
  • Re: WxWidgets : Frame e Window

    Rubik ha scritto:


    Speriamo che Alexv, ci dia lumi, perché anche se troviamo una soluzione per l'interfaccia hai ancora il problema del linguaggio, il codice seguente per console in C#, scritto ora in 5 minuti, legge un file testo, questo:
    
    ID: ;NOME: ;COGNOME: ;DATA di nascita: ;RESIDENZA: ;;;
    04;Carlo;Ragaini;02/03/1989;Roma;
    02;Mario;Pagani;08/07/1990;Milano;
    08;Gianni;Luzi;12/06/1989;Palermo;
    01;Pino;Brusin;09/12/1991;Palermo;
    
    estrae la prima riga e la divide per definire i nomi dei campi, legge tutte le righe a mo di records e li mostra con i rispettivi nomi dei campi.
    finito il compito i record vengono riordinati e rimostrati in ordine.
    (...)
    l'esempio è banale, ma comunque si adatta all'input, se aggiungi campi nell'intestazione o nuovi records li leggerà, prova a replicarlo in C, se l'esempio fosse più complicato il divario tra C# e C, si accentuerebbe.
    C'è anche il fatto che gli esempi per imparare che troverai in rete per il C per larga maggioranza non funzioneranno, perché saranno per un ambiente che non hai, usano una libreria che non hai, ha delle istruzioni per un compilatore diverso dal tuo, e da ultimo è per Linux. Più il tuo codice è avanzato e più quello che cerchi sarà sommerso da una valanga di codici inadeguati.
    Non ho mai parlato di C e windows.h spero che muoia male, rimpiazzato con qualcosa di degno di questo secolo (winRT e winUI sembrano sulla buona strada).
    Ma vedi, si tratta sempre di chi c'ha la libreria più grossa. Nel tuo caso hai usato quella che Microsoft ti ha fornito con l'ambiente di sviluppo, cosa che QtCreator ad esempio non manca di fare.

    Mi sono permesso comunque di soddisfare la tua curiosità (ma non prenderlo come una polemica ) senza installare niente di terze parti, anche se ammetto che la gestione di stringhe e file della libreria standard ha ancora passi avanti da fare, mentre in Qt potevo usare un sempilce readAll.
    
    #include <iostream>
    #include <string>
    #include <sstream>
    #include <fstream>
    #include <vector>
    #include <cstdlib>
    #include <set>
    
    
    using namespace std;
    
    void Visualizza (const multiset<string>& records, const vector<string>& campi);
    
    int main()
    {
        ifstream leggiFile("miofile.txt");
        if(!leggiFile.is_open()) exit(-1);
        vector<string> righe;   //elenco di righe
        for(string riga; getline(leggiFile,riga) ;) righe.push_back(riga);  //ottiene l'elenco di righe dal file
        vector<string> campi;
        istringstream leggiCampi(righe[0]);
        for(string campo;getline(leggiCampi,campo,';');) campi.push_back(campo); //ottiene elenco dei campi
        multiset<string> records;  //multiset inserisce i record gia' ordinati
        for(int i = 1; i < righe.size(); ++i) records.insert(righe[i]); //ottiene i record
        cout<<"------ ORDINATI ------\n";
        Visualizza(records, campi);
        system("pause");
    }
    
    void Visualizza(const multiset<string>& records, const vector<string>& campi)
    {
        for(auto& riga : records)
        {
            istringstream leggiDati(riga);
            int i = 0;
            for(string dato; getline(leggiDati,dato,';');)
                cout<<campi[i++]<<" "<<dato<<"\n";
            cout<<"\n\n";
        }
        return;
    }
    
    Comunque anche C# usato in modo avanzato, richiede una certa conoscenza ad esempio di come si usa un dispacher.
  • Re: WxWidgets : Frame e Window

    Alexv ha scritto:


    Non ho mai parlato di C e windows.h spero che muoia male, rimpiazzato con qualcosa di degno di questo secolo (winRT e winUI sembrano sulla buona strada).
    Ma vedi, si tratta sempre di chi c'ha la libreria più grossa. Nel tuo caso hai usato quella che Microsoft ti ha fornito con l'ambiente di sviluppo, cosa che QtCreator ad esempio non manca di fare.
    winRT e winUI, ci guardo, ma se hai qualche dritta sono affamato di info selezionate, in rete c'è un guazzabuglio infernale!!!

    Se uso Win mi affido a VS, lo uso in VB.Net C# e per gioco anche C (C++ ti dico poi)
    QT è anche multipiattaforma, per ora l'ho accantonato, troppo da configurare...

    Alexv ha scritto:


    Mi sono permesso comunque di soddisfare la tua curiosità (ma non prenderlo come una polemica ) senza installare niente di terze parti, anche se ammetto che la gestione di stringhe e file della libreria standard ha ancora passi avanti da fare, mentre in Qt potevo usare un sempilce readAll.
    Guarda che hai capito male, quella che pensavi potesse essere da me interpretata come polemica, è invece proprio quello che cerco, e è quello che invito tutti a fare, invogliarci a spendere tempo anche nel C++ o altro, e il tuo esempio assolve a questa funzione, purtroppo non sono agli inizi, in VB.Net e C# mi trovo bene, quando scrivo qualcosa di generico in C sorrido e penso ma chi me lo fa fare... invece mi piace avere il controllo dei dati in memoria fino alla gestione del singolo bit.
    Attualmente ho saltato il C++ del quale so solo che non è un C esteso, ma un linguaggio nuovo con possibilità avanzate.

    Il tuo codice lo dimostra e funziona alla grande.

    Rosmarino restando in C++ cosa è meglio che fa?
    Installa Visualstudio o QT5?
    Per quello che vuole lui dico bene che con CodeBlocks si complica la vita?
  • Re: WxWidgets : Frame e Window

    A uno che chiede con cosa iniziare direi assolutamente C# o VB.net (spiace per quest'ultimo, sempre più bistrattato). Ma forse chi proviene da C può trovare irritante l'approccio OOP a cui ti obbliga C#, trovarsi più a suo agio con C++ (comunque sempre più distante da C).
    In generale suggerisco quelli che hai detto, stavo solo facendo notare che con i giusti strumenti C++ non è poi quel mostro come il C.
    Va tenuto presente, però, che tutto il corredo .net che ti da Visual Studio solo ultimamente sta vedendo dei porting ufficiali su altre piattaforme.

    WinUI è l'ultimo dei tanti rimpiazzi a Windows.h (la parte grafica) che MS si è inventata; winRT per altre funzioni oltre la grafica. La doc online mi sembra un po' incasinata.
  • Re: WxWidgets : Frame e Window

    Hi , bit-pal
    é grande poter confrontare così facilmente le proprie idee .
    Penso che pochi si rendano conto di quanto bella è quest’epoca .
    Prestare attenzione ai problemi di altri , dedicare parte del proprio tempo per capire , studiare e proporre soluzioni è segno distintivo di persone molto positive .
    Sono interessato agli argomenti che vengono proposti anche se , più semplicemente , mi accontenterei di poche dritte . Capisco i suggerimenti verso soluzioni razionali , ma quello che cerco è la padronanza di pochissimi strumenti che mi consentano di testare vie fuoristrada .
    Per spiegarmi meglio : credo di non aver bisogno di chiarimenti su C e ( forse con un po' di presunzione ) neanche su C++ . Capisco la logica delle classi-oggetti ( posso non capire la logica di un membro di una specifica classe perché non comprendo lo schema mentale di chi l’ha costruito ) , ma non penso sia buona programmazione cercare di trasformare tutto il codice in una sequenza di classi . Credo vadano usate se realmente servono . Ci sono , secondo me , altre possibilità per ottenere i vantaggi offerti dalla programmazione tipo OOP senza usare le classi ( non dico di non utilizzarle mai , solo quando è utile ).
    Per esempio , la gestione degli eventi che ho trovato in wxWidgets . Se non ho capito male viene inserito un identificatore unico ( in ogni oggetto ) che viene attivato dal rilevamento di un input generato dal mouse in un certo spazio rientrante in quell’oggetto . Poi segue la gestione dell’evento tramite tabelle o direttamente con bind() . Tutto dovrebbe partire dalla rilevazione della posizione del cursore a seguito del movimento del mouse con relativo click tasto sinistro/destro .
    Ecco , datemi un’istruzione del tipo GetPosMouse ( ) con la restituzione delle coordinate attuali del cursore ( eventualmente con anche se cliccato tasto sinistro/destro ) e penso io a gestire gli eventi scavalcando tutta la sequenza degli oggetti , delle tabelle , dei bind() .
    Di seguito ( sempre in stile grafico ) , datemi un’istruzione per :
    • riprodurre qualcosa sullo schermo senza dover passare dagli oggetti wxFrame o wxWindow ( che non mi servono )
    • creare una finestra trasparente , più grande dello schermo
    • scrollare tale finestra Nord-Sud e Est-Ovest rispetto allo schermo
    • creare / cancellare dei campi-di-input nelle posizioni volute su quella finestra
    • leggere e scrivere su tali campi
    Possibile che non si possa fare ?
    P.S. :
    • avrei supposto che l’uso di wxWindow seguisse lo schema d’uso di wxFrame ma mi sembra che non sia così e non capisco perché .
    • in CodeBlocks+minGW+wxWidgets+C++ aprendo un new project stile wxWidgets , nel codice proposto non c’è traccia degli eventi ridimensionamento della finestra , perché ?
  • Re: WxWidgets : Frame e Window

    Rosmarino ha scritto:


    Possibile che non si possa fare ?
    Se non ti piace una libreria prendi e la cambi, no? Qual è il punto di arrivo di questo thread?

    Il problema, secondo me, è che sei fossilizzato su quello che conosci e non vuoi uscire dal recinto. Pure a me non piace il paradigma OOP e se potessi farei tutto in C, però bisogna farsene una ragione e utilizzare gli strumenti giusti al posto giusto
  • Re: WxWidgets : Frame e Window

    Hi , bit-pal
    scusatemi , forse ho sbagliato l’impostazione della mia domanda .
    La base di partenza è che vorrei utilizzare C++ per divertirmi un po' . Provengo da C e sono solo parzialmente d’accordo con chi giudica C o C++ per masochisti in quanto linguaggi troppo propensi a generare errori e poco leggibili. Dipende sempre da come vengono usati .
    Su indicazioni ricavate da letture varie ero propenso ad utilizzare come strutture CodeBlocks+minGW+wxWidgets per dare un po' di grafica alla programmazione in C++
    ma ad un primo esame diretto mi sembra che ci siano alcuni presupposti che non ho compreso :
    • librerie tipo wxWidgets impongono l’uso assoluto delle classi ?
    • o consentono anche l’uso di istruzioni elementari, al di fuori delle classi, ad esempio :
    ? un’ istruzione tipo GetPosCursore() che restituisca le coordinate attuali del cursore e il click tasto sinistro/destro ?
    ? la creazione di spazi proiettabili sullo schermo senza dover passare da classi tipo wxFrame ?
    ? La possibilità di I/O senza dover utilizzare le classi predisposte ad hoc ?
    Se esistono librerie che consentono questo , non avrei difficoltà a cambiare le strutture di cui sopra . Mi va molto bene l’uso di IDE e librerie a condizione che non mi impongano di fare programmi prefissati . Il bello di programmare è fare ciò che si vuole .
  • Re: WxWidgets : Frame e Window

    Rosmarino ha scritto:


    Provengo da C e sono solo parzialmente d’accordo con chi giudica C o C++ per masochisti in quanto linguaggi troppo propensi a generare errori e poco leggibili. Dipende sempre da come vengono usati .
    L'ho scritto io ma non era una critica al linguaggio, adattissimo per creare dll con routine ad alta efficienza, era riferito allo scegliere il C/C++, per creare un programma basato su interfaccia grafica, quando esiste VisualStudio e C# che ti semplifica la vita, se scegli C++ dovrai investire molto sullo studio di cose che a tuo dire, ti interessano poco. Anche se mi tirerò dietro degli insulti meritati, non è vero che se programmi in C# devi usare per forza le classi, puoi tranquillamente mettere tutto il codice in un'unica classe, quella predefinita e programmare in modo procedurale come in C.

    Rosmarino ha scritto:


    Su indicazioni ricavate da letture varie ero propenso ad utilizzare come strutture CodeBlocks+minGW+wxWidgets per dare un po' di grafica alla programmazione in C++
    ma ad un primo esame diretto mi sembra che ci siano alcuni presupposti che non ho compreso :
    • librerie tipo wxWidgets impongono l’uso assoluto delle classi ?
    • o consentono anche l’uso di istruzioni elementari, al di fuori delle classi, ad esempio :
    ? un’ istruzione tipo GetPosCursore() che restituisca le coordinate attuali del cursore e il click tasto sinistro/destro ?
    ? la creazione di spazi proiettabili sullo schermo senza dover passare da classi tipo wxFrame ?
    ? La possibilità di I/O senza dover utilizzare le classi predisposte ad hoc ?
    Se esistono librerie che consentono questo , non avrei difficoltà a cambiare le strutture di cui sopra .
    Non so rispondere.

    Rosmarino ha scritto:


    Mi va molto bene l’uso di IDE e librerie a condizione che non mi impongano di fare programmi prefissati . Il bello di programmare è fare ciò che si vuole .
  • Re: WxWidgets : Frame e Window

    Hi , bit-pal
    @Rubik , non so come riprendere le frasi alle quali rispondere; è un metodo comodo, chiaro e preciso che non so ancora usare . Comunque mi riferisco alle istruzioni base tipo GetPosCursore() e tutte le altre , anche di tipo I/O che ritengo debbano essere all’origine per la costruzione delle classi . Ci sono librerie C++ che le rendono disponibili ?
    @ Weierstrass “Il problema, secondo me, è che sei fossilizzato su quello che conosci e non vuoi uscire dal recinto”
    ti assicuro che non è così . Anche quando non programmavo più, ho seguito con molto interesse la divulgazione di OOP . La trovavo geniale . Ora , esaminandola nel dettaglio e nelle sue applicazioni pratiche , sono un po' meno entusiasta . Mi sembra molto utile per chi vuole ottenere applicazioni in tempi rapidi , senza troppa attenzione alle necessità dei problemi da risolvere , piegati all’opportunità di utilizzare mattoncini prefabbricati . Senza nessuna offesa , né tanto meno polemica , mi sembra una programmazione LEGO .
    Presto avremo programmi “Hello Word” di 1 GB .
    Gli strumenti giusti , per me , sono le istruzioni di base , che dovrebbero essere disponibili in ogni libreria.
    Ripassando a mente il mio vecchio programma ed in prospettiva come vorrei fosse il nuovo , non trovo occasioni di utilizzare più di un oggetto per ogni classe che eventualmente dovessi costruire . Per la chiarezza del codice bastano le normali funzioni . Sarà perché , provenendo da UNIX sono portato ad utilizzare la struttura che ritengo più semplice in assoluto : la lista .
    Penso che ognuno di noi abbia uno schema mentale unico , come giusto che sia , e penso che spesso sia difficile capire la forma mentis altrui . Può essere che il mio modo di programmare sia molto distante dagli standard attuali e che quindi tutti voi facciate fatica a capire quello che vorrei esprimervi . Mi scuso .
  • Re: WxWidgets : Frame e Window

    Rosmarino ha scritto:


    Hi , bit-pal
    @Rubik , non so come riprendere le frasi alle quali rispondere; è un metodo comodo, chiaro e preciso che non so ancora usare .
    se vuoi rispondere ad un messaggio inglobandolo nella tua risposta (citando), devi cliccare il tastino con le doppie virgolette:
    citando.png
    citando.png

    Rosmarino ha scritto:


    Comunque mi riferisco alle istruzioni base tipo GetPosCursore() e tutte le altre , anche di tipo I/O che ritengo debbano essere all’origine per la costruzione delle classi . Ci sono librerie C++ che le rendono disponibili ?
    Nella libreria windows.h ci sono le istruzioni: GetKeyState() GetCursorPos() ScreenToClient(,), se riguardi il gioco del 15 che ti ho postato puoi vedere come usarle, naturalmente l'handle deve essere quello della finestra che ti interessa.

    Per studiare windows.h: https://docs.microsoft.com/en-us/windows/win32/learnwin32/your-first-windows-program

    Il post era questo:

    Rubik ha scritto:


    
    #include <stdio.h>
    #include <stdlib.h>
    #include <time.h>
    #include <windows.h>
    #include <ctype.h>
    
    /*************************************
    *            GIOCO DEL 15            *
    *  Si gioca in console con il mouse  *
    *  il puzzle è sempre risolvibile    *
    *************************************/
    
    // **** costanti
    const char RigSopra[]={(CHAR)201,(CHAR)205,(CHAR)205,(CHAR)205,(CHAR)205,(CHAR)203,(CHAR)205,(CHAR)205,(CHAR)205,(CHAR)205,(CHAR)203,(CHAR)205,(CHAR)205,(CHAR)205,(CHAR)205,(CHAR)203,(CHAR)205,(CHAR)205,(CHAR)205,(CHAR)205,(CHAR)187,'\0'};
    const char RigheCentro[]={(CHAR)204,(CHAR)205,(CHAR)205,(CHAR)205,(CHAR)205,(CHAR)206,(CHAR)205,(CHAR)205,(CHAR)205,(CHAR)205,(CHAR)206,(CHAR)205,(CHAR)205,(CHAR)205,(CHAR)205,(CHAR)206,(CHAR)205,(CHAR)205,(CHAR)205,(CHAR)205,(CHAR)185,'\0'};
    const char RigSotto[]={(CHAR)200,(CHAR)205,(CHAR)205,(CHAR)205,(CHAR)205,(CHAR)202,(CHAR)205,(CHAR)205,(CHAR)205,(CHAR)205,(CHAR)202,(CHAR)205,(CHAR)205,(CHAR)205,(CHAR)205,(CHAR)202,(CHAR)205,(CHAR)205,(CHAR)205,(CHAR)205,(CHAR)188,'\0'};
    // in aControllo, gli indici in base zero del vettore iSequenza che devono essere esplorati, in base alla casella cliccata
    const unsigned int aControllo[16][4]={{1, 4, 0, 0}, {0, 2, 5, 1}, {1, 3, 6, 2}, {2, 7, 3, 3}, {0, 5, 8, 4}, {4, 1, 6, 9}, {5, 2, 7, 10}, {11, 3, 6, 7}, {4, 9, 12, 8}, {8, 5, 10, 13}, {14, 9, 6, 11}, {15, 10, 7, 11}, {8, 13, 12, 12}, {12, 9, 14, 13}, {13, 10, 15, 14}, {14, 11, 15, 15}};
    const char Titolo[]="Gioco del15 CB2021";
    
    // **** pubbliche
    struct {
        unsigned int riga; // base 1
        unsigned int colonna; // base1
        unsigned int casella; // base 0
        unsigned int mosse;
        unsigned int MouseButton; // 1 = tasto sinistro, 2 = tasto destro
        unsigned char iSequenza[16]; // contiene sempre lo stato del gioco
    }GiocoDel15;
    
    // **** prototipi
    int Schermo(HANDLE Cons); // disegna lo schema con i numeri
    int SeqValida(); // 0 = la sequenza non è risolvibile, 1 = la sequenza è risolvibile
    void MenuScelta();
    void GenSequenza(); // genera la sequenza ordinata
    void mescola(HANDLE Cons);
    void TrovaCasella(int x, int y, HANDLE Cons); // aggiorna la struct GiocoDel15 in base alla casella cliccata
    
    int main()
    {
        SetConsoleTitle(Titolo);
        POINT pCoor;
        HWND hwnd=0;
    
        //attende la creazione della finestra per prelevare hwnd
        while (hwnd==0)
            hwnd=FindWindow(NULL, Titolo); // handle della finestra
        //------------------------------------------------------
    
        HANDLE console=GetStdHandle(STD_OUTPUT_HANDLE); // handle del processo
    
        MenuScelta();
        GenSequenza(); // sequenza ordinata
        Schermo(console); // prima visualizzazione schema
    
        while(1){ // loop infinito mouse
            Sleep(50); // lascia la CPU libera, limita i cicli in 1000/50=20 al secondo
            if((GetKeyState(GiocoDel15.MouseButton) & 0x8000) != 0){ // bottone mouse
                GetCursorPos(&pCoor); // coordinate assolute cursore
                ScreenToClient(hwnd, &pCoor); // coordinate relative cursore
                TrovaCasella(pCoor.x, pCoor.y, console); // TrovaCasella modifica la struct GiocoDel15
                if (GiocoDel15.riga!=0 && GiocoDel15.colonna!=0){ // click dentro lo schema
                    for (int i=0; i<4; i++){ // controllo in 4 direzioni predefinite in aControllo
                       if (GiocoDel15.iSequenza[aControllo[GiocoDel15.casella][i]]==0){ // è la casella vuota, swap
                            GiocoDel15.iSequenza[aControllo[GiocoDel15.casella][i]]=GiocoDel15.iSequenza[GiocoDel15.casella]; // scrivo il valore della casella cliccata nella casella vuota
                            GiocoDel15.iSequenza[GiocoDel15.casella]=0; // nella casella cliccata metto zero, lo swap è completo
                            GiocoDel15.mosse++; // incremento le mosse
                            /* per test
                            printf("\n\nCasella = %d", GiocoDel15.casella+1);
                            printf(" Vuota = %d", aControllo[GiocoDel15.casella][i]+1);*/
                            break;
                       }
                    }
                    int risolto=Schermo(console); // aggiorno lo schermo, la funzione restituisce se c'è soluzione
                    printf("\n\n  ");
                    if (risolto==1){
                        SetConsoleTextAttribute(console, 0x0E); // 0xE giallo 0x0 nero
                        printf(" Risolto,");
                        SetConsoleTextAttribute(console, 0x0A); // 0xA verde 0x0 nero
                    }
                    printf(" mosse = %d",GiocoDel15.mosse); // visualizzo le mosse
                }
            Sleep(200); // Ritardo evita doppio click, al massimo vengono rilevati 5 click al secondo
            }
        }
    }
    
    int Schermo(HANDLE Cons){
    
        system("cls");
        int i=0;
        SetConsoleTextAttribute(Cons, 0x0B); // 0xB ciano 0x0 nero
        if (GiocoDel15.MouseButton==1)
            printf("\n   GIOCO DEL15  W7 LBUTTON\n");
        else
            printf("\n   GIOCO DEL15 W10 RBUTTON\n");
    
        printf("\n   ");
    
        // disegno schema con sequenza ***************
        SetConsoleTextAttribute(Cons, 0xCF); // 0xF bianco 0xC rosso
        printf("                       ");
        SetConsoleTextAttribute(Cons, 0x0B); // 0xB ciano 0x0 nero
        printf("\n   ");
        SetConsoleTextAttribute(Cons, 0xCF); // 0xF bianco 0xC rosso
        printf(" %s ",RigSopra);
        for (i=0; i<16; i+=4){
            SetConsoleTextAttribute(Cons, 0x0B); // 0xB ciano 0x0 nero
            printf("\n   ");
            SetConsoleTextAttribute(Cons, 0xCF); // 0xF bianco 0xC rosso
            // il numero zero viene sostituito con gli spazi (casella vuota)
            for (int ind=0; ind<4; ind++){
                printf(" %c ", (CHAR)186);
                if (GiocoDel15.iSequenza[ind+i]==0) printf("  "); else printf("%02d", GiocoDel15.iSequenza[ind+i]);
            }
            printf(" %c ", (CHAR)186);
            SetConsoleTextAttribute(Cons, 0x0B); // 0xB ciano 0x0 nero
            printf("\n   ");
            SetConsoleTextAttribute(Cons, 0xCF); // 0xF bianco 0xC rosso
            if (i==12) printf(" %s ", RigSotto); else printf(" %s ", RigheCentro);
        }
        SetConsoleTextAttribute(Cons, 0x0B); // 0xB ciano 0x0 nero
        printf("\n   ");
        SetConsoleTextAttribute(Cons, 0xCF); // 0xF bianco 0xC rosso
        printf("                       ");
        SetConsoleTextAttribute(Cons, 0x0B); // 0xB ciano 0x0 nero
        printf("\n   ");
        printf("\n    [MESCOLA]     [ESCI]");
        SetConsoleTextAttribute(Cons, 0x0A); // 0xA verde 0x0 nero
        //****************************************
    
        /* per test*/
        printf("\n\n   Sequenza = [");
        for (i=0; i<16; i++){
            printf("%02d", GiocoDel15.iSequenza[i]); // mostra lo stato della sequenza
        }
        printf("]");
    
        if (GiocoDel15.iSequenza[15]==0 ){
            printf(" SeqValida = %d", SeqValida()); // verifica se la sequenza è risolvibile: 1=si, 0=no
        }
    
    
        for (i=0; i<15; i++){
            if (GiocoDel15.iSequenza[i] != i+1) return 0;  // non risolto
        }
        return 1; // risolto
    }
    
    int SeqValida(){ // usata in fase di test
    
        unsigned int coppie = 0;
        for (int i=0; i<15;i++){
            for (int y=i+1; y<15;y++){
                if (GiocoDel15.iSequenza[i] < GiocoDel15.iSequenza[y]) coppie++;
            }
        }
        return coppie%2;
    }
    
    void MenuScelta(){
    
        GiocoDel15.MouseButton=0;
        while(GiocoDel15.MouseButton==0){
            system("cls");
            printf("\n   ***** GIOCO DEL15 *****\n");
            printf("\n   si gioca con il mouse, le coordinate cambiano in base al S.O.\n");
            printf("\n   1) Win 7 tasto sinistro mouse");
            printf("\n   2) Win10 tasto destro mouse\n");
            printf("\n   0) Esci\n");
            printf("\n      Tua scelta : ");
    
            char scelta=getchar();
    
            switch (scelta){
    
            case '1': // Win7
                GiocoDel15.MouseButton = 1; // VX_LBUTTON
                break;
    
            case '2': // Win10
                GiocoDel15.MouseButton = 2; // VX_RBUTTON
                break;
    
            case '0': // esci
                printf("\n");
                exit(0);
            }
        }
    }
    
    void GenSequenza(){
        // riempimento vettore ordinato
        for (int i=0; i<15; i++)GiocoDel15.iSequenza[i]=i+1;
        GiocoDel15.iSequenza[15]=0;
    }
    
    void mescola(HANDLE Cons){
    
        GenSequenza(); // si parte con la sequenza ordinata con zero finale
        // mescolamento vettore
        srand((unsigned) time(NULL)); // init random
    
        for (int i=0; i<30; i++){ // se la sequenza ordinata viene mescolata un numero pari di volte(es 30), è sempre valida
            int ind = rand() % 14 + 1 ; // (1/14), non sposto mai lo zero finale
            unsigned char tmp = GiocoDel15.iSequenza[ind]; // inizio swap
            GiocoDel15.iSequenza[ind] = GiocoDel15.iSequenza[0];
            GiocoDel15.iSequenza[0] = tmp; // fine swap
        }
        GiocoDel15.mosse = 0;
        Schermo(Cons); // visualizzazione
    }
    
    void TrovaCasella(int x, int y, HANDLE Cons){ // controllo coordinate mouse
    
        GiocoDel15.riga = 0; // base 1
        GiocoDel15.colonna = 0; // base 1
        GiocoDel15.casella = 0; // base zero
    
        if (GiocoDel15.MouseButton==1){ // Win7
            if (x>39 && x<73) GiocoDel15.colonna = 1; // casella 0
            if (x>79 && x<113) {GiocoDel15.colonna = 2; GiocoDel15.casella = 1;}
            if (x>119 && x<153) {GiocoDel15.colonna = 3; GiocoDel15.casella = 2;}
            if (x>158 && x<193) {GiocoDel15.colonna = 4; GiocoDel15.casella = 3;}
            if (y>55 && y<76) GiocoDel15.riga = 1;
            if (y>79 && y<100) {GiocoDel15.riga = 2; GiocoDel15.casella +=4;}
            if (y>103 && y<123) {GiocoDel15.riga = 3; GiocoDel15.casella +=8;}
            if (y>129 && y<148) {GiocoDel15.riga = 4; GiocoDel15.casella +=12;}
            if (x>37 && x<100 && y>180 && y<190) mescola(Cons);
            if (x>149 && x<188 && y>180 && y<190) {printf("\n"); exit(0);}
        }
        else{ // Win10
            if (x > 39 && x < 74) GiocoDel15.colonna = 1; // casella 0
            if (x > 78 && x < 112) { GiocoDel15.colonna = 2; GiocoDel15.casella = 1; }
            if (x > 119 && x < 154) { GiocoDel15.colonna = 3; GiocoDel15.casella = 2; }
            if (x > 158 && x < 192) { GiocoDel15.colonna = 4; GiocoDel15.casella = 3; }
            if (y > 76 && y < 103) GiocoDel15.riga = 1;
            if (y > 107 && y < 135) { GiocoDel15.riga = 2; GiocoDel15.casella += 4; }
            if (y > 140 && y < 167) { GiocoDel15.riga = 3; GiocoDel15.casella += 8; }
            if (y > 173 && y < 197) { GiocoDel15.riga = 4; GiocoDel15.casella += 12; }
            if (x > 37 && x < 100 && y>240 && y < 251) mescola(Cons);
            if (x > 149 && x < 188 && y>240 && y < 251) { printf("\n"); exit(0); }
        }
        // printf( "\nPosizione x = %d y = %d rig = %d col = %d cas = %d",x ,y, GiocoDel15.riga, GiocoDel15.colonna, GiocoDel15.casella);
    }
    

    Rosmarino ha scritto:


    @ Weierstrass “Il problema, secondo me, è che sei fossilizzato su quello che conosci e non vuoi uscire dal recinto”
    ti assicuro che non è così . Anche quando non programmavo più, ho seguito con molto interesse la divulgazione di OOP . La trovavo geniale . Ora , esaminandola nel dettaglio e nelle sue applicazioni pratiche , sono un po' meno entusiasta . Mi sembra molto utile per chi vuole ottenere applicazioni in tempi rapidi , senza troppa attenzione alle necessità dei problemi da risolvere , piegati all’opportunità di utilizzare mattoncini prefabbricati . Senza nessuna offesa , né tanto meno polemica , mi sembra una programmazione LEGO .
    Presto avremo programmi “Hello Word” di 1 GB .
    Gli strumenti giusti , per me , sono le istruzioni di base , che dovrebbero essere disponibili in ogni libreria.
    Ripassando a mente il mio vecchio programma ed in prospettiva come vorrei fosse il nuovo , non trovo occasioni di utilizzare più di un oggetto per ogni classe che eventualmente dovessi costruire . Per la chiarezza del codice bastano le normali funzioni . Sarà perché , provenendo da UNIX sono portato ad utilizzare la struttura che ritengo più semplice in assoluto : la lista .
    Penso che ognuno di noi abbia uno schema mentale unico , come giusto che sia , e penso che spesso sia difficile capire la forma mentis altrui . Può essere che il mio modo di programmare sia molto distante dagli standard attuali e che quindi tutti voi facciate fatica a capire quello che vorrei esprimervi . Mi scuso .
    Quello che dici sono parole sante e credo che nessun programmatore non le condivida, se hai ritenuto che le risposte che hai ricevuto erano in antagonismo con quanto chiedevi, ti assicuro che non è così.

    Dopo questa affermazione, spero che non predi quello che ripeto come una forzatura, ma come un'esposizione da chi ha già affrontato i tuoi problemi.
    I mattoncini Lego che hai nominato non sono per la stesura del codice del tuo programma, ma per la realizzazione dell'interfaccia, tediosa da programmare. Quando vuoi inserire un bottone cliccabile in una finestra di windows lo puoi fare in due modi:
    1) scrivere tutto il codice da solo dopo aver acquisito tutte le conoscenze di come windows gestisce le finestre, con i vari messaggi che si scambiano e di come interpretarli (non c'entra nulla con il C++ è tutto da imparare e è bene conoscerne le basi).
    2) usare un codice già preconfezionato che esegue tutte le operazioni per te, tu dovrai decidere dove posizionare il bottone, la sua dimensione, il colore, l'immagine che lo rappresenta, il testo entrocontenuto e cosa deve succedere se l'utente lo clicca. Quando l'utente clicca parte una tua routine, nessuno la scrive per te).

    L'opzione due può essere espletata in due modi:
    1) usi una libreria dove tutto avviene ancora a livello di codice da imparare e gestire.
    2) usi un IDE che ha la progettazione dell'interfaccia in modo visuale.

    L'opzione due esiste in VisualStudio e non è stata creata per programmatori svogliati, ma per programmatori che si vogliono concentrare sul suo programma che svolgerà operazioni uniche e non generalizzabili. Invece mettere un bottone è un'operazione usuale e generalizzabile.
    Per il peso dell'applicazione, sia che il codice lo scrivi tu, lo prendi da una libreria, o da uno strumento di VisualStudio, non cambia. A meno che il tuo codice è privo di controlli, non gestisce le trasformazioni dello spazio colore in base al S.O., non si adatta agli ambienti 32/64 bit, non è ancorabile alla finestra ecc. ecc.

    Tolto il fardello dell'interfaccia, il programma lo scrivi come vuoi tu, se lavori da solo deve andare bene solo a te.
  • Re: WxWidgets : Frame e Window

    Hi , bit-pal
    grazie Rubik . Mi studio window.h
  • Re: WxWidgets : Frame e Window

    Rosmarino ha scritto:


    Hi , bit-pal
    grazie Rubik . Mi studio window.h
    Mi hai messo voglia...
    Ho messo a frutto quel poco che so, il codice seguente se lo incolli in un progetto Win32 GUI project di CODE::BLOCKS, legge le coordinate del mouse assolute e relative, la dimensione della finestra al resize, la pressione dei tasti del mouse, la tastiera e le mostra sulla finestra Win.
    Fatto in velocità, correzioni ben volute.
    
    /******************************************************************************
        CODE::BLOCKS aprire un progetto C o C++ Win32 GUI project
    
        Altrimenti progetto console ma aggiungere nelle impostazioni:
        "Setting/Compiler/Linker setting/Other compiler setting" i seguenti percorsi:
    
        c:\Windows\System32\gdi32.dll
        c:\Windows\System32\kernel32.dll
        c:\Windows\System32\user32.dll
        c:\Windows\System32\comctl32.dll
    
        o quelli disponibili, in questo progetto solo gdi32.dll viene usata
    
        Finestra Win ridimensionabile, paint testo, coord mouse assolute
        e relative e alcuni messaggi mouse e tastiera inviati dalla finestra
    ******************************************************************************/
    
    #include <windows.h>
    
    /// CONSTANTS
    
    const char *Name = "Coordinate mouse";
    const char *Prog = "Coordinate mouse";
    const DWORD Win = WS_OVERLAPPEDWINDOW;
    const WORD Wwin = 800;  // larghezza iniziale della finestra
    const WORD Hwin = 600;  // altezza iniziale della finestra
    
    /// PROTOTYPIES
    
    BOOL Register_Class( HINSTANCE hIst );
    BOOL Create_Window( HINSTANCE hIst, int show );
    void Show_PAINT( HWND hwnd, char Text[20] );
    void Error( const char *msg, HWND hwnd );
    
    /// FUNCTIONS
    
    int WINAPI WinMain(HINSTANCE hIst, HINSTANCE hPrevInst, LPSTR cmd, int show ) {
        MSG msg = {0};
    
        if( !Register_Class(hIst) )
            { Error( "Classe non registrata. ", NULL ); return 0; }
    
        if( !Create_Window(hIst, show) )
            { Error( "Finestra non creata. ", NULL ); return 0; }
    
        while( GetMessage( &msg, NULL, 0, 0 ) > 0 ){
            DispatchMessage( &msg );
        }
        return 0;
    }
    
    LRESULT CALLBACK WndProc( HWND hWnd, UINT msg, WPARAM wPar, LPARAM lPar ) {
         char Text[10];
         switch( msg ) {
            // l'IDE mostra tutti i parametri WM_XXXX usabili
            case WM_LBUTTONDOWN:
                strcpy(Text, "L_BUTTON\0");
                InvalidateRect( hWnd, NULL, TRUE ); // rinfresca il form
                Show_PAINT( hWnd, Text );
                break;
    
            case WM_RBUTTONDOWN:
                strcpy(Text, "R_BUTTON\0");
                InvalidateRect( hWnd, NULL, TRUE ); // rinfresca il form
                Show_PAINT( hWnd, Text );
                break;
    
            case WM_MBUTTONDOWN:
                strcpy(Text, "M_BUTTON\0");
                InvalidateRect( hWnd, NULL, TRUE ); // rinfresca il form
                Show_PAINT( hWnd, Text );
                break;
    
            case WM_MOUSEWHEEL:
                strcpy(Text, "WEEL\0");
                InvalidateRect( hWnd, NULL, TRUE ); // rinfresca il form
                Show_PAINT( hWnd, Text );
                break;
    
            case WM_KEYDOWN:
                strcpy(Text, "KEYBOARD\0");
                InvalidateRect( hWnd, NULL, TRUE ); // rinfresca il form
                Show_PAINT( hWnd, Text );
                break;
    
            case WM_MOUSEMOVE:
                strcpy(Text, "MOVE\0");
                InvalidateRect( hWnd, NULL, TRUE ); // rinfresca il form
                Show_PAINT( hWnd, Text );
                Sleep(50); // evita sfarfallio
                break;
    
            case WM_SIZE:
                strcpy(Text, "SIZE\0");
                InvalidateRect( hWnd, NULL, TRUE ); // rinfresca il form
                Show_PAINT( hWnd, Text );
                Sleep(1); // evita sfarfallio
                break;
    
            case WM_CLOSE:
                PostQuitMessage( 0 );
                break;
    
            default:
                return DefWindowProc( hWnd, msg, wPar, lPar );
        }
        return 0;
    }
    
    BOOL Register_Class( HINSTANCE hIst ) {
        WNDCLASS wc      = {0};
        wc.lpfnWndProc   = WndProc;
        wc.hInstance     = hIst;
        wc.hCursor       = LoadCursor( NULL, IDC_ARROW );
        wc.hbrBackground = (HBRUSH)GetStockObject( GRAY_BRUSH );
        wc.lpszClassName = Name;
        return RegisterClass( &wc ) != 0;
    }
    
    BOOL Create_Window( HINSTANCE hIst, int mostra ) {
        RECT r = { 0, 0, Wwin, Hwin };
        AdjustWindowRect( &r, Win, FALSE );
        OffsetRect( &r, -r.left+10, -r.top+10 );
        HWND hwnd = CreateWindow(Name, Prog, Win, r.left, r.top, r.right-r.left, r.bottom-r.top, 0, 0, hIst, NULL );
        if( hwnd != NULL ) ShowWindow( hwnd, mostra );
        return hwnd != NULL;
    }
    
    /// Coordinate
    
    void Show_PAINT( HWND hwnd, char Text[] ) {
        POINT pCoor;
        GetCursorPos(&pCoor); // coordinate assolute cursore
        int x=pCoor.x;
        int y=pCoor.y;
        ScreenToClient(hwnd, &pCoor); // coordinate relative cursore
        PAINTSTRUCT ps;
        HDC hdc = BeginPaint( hwnd, &ps );
        RECT r;
        char buff[128];
        GetClientRect( hwnd, &r );
        wsprintf( buff, "Finestra %d x %d\n\nPosWin %d x %d\n\nPosDesk %d x %d\n\n%s", r.right, r.bottom, pCoor.x, pCoor.y, x, y, Text );
        InflateRect( &r, -7, -7 );
        DrawText( hdc, buff, -1, &r, DT_EXPANDTABS );
        EndPaint( hwnd, &ps );
    }
    
    void Error( const char *msg, HWND hwnd ) {
        MessageBox( hwnd, msg, Prog, MB_ICONERROR );
    }
    
Devi accedere o registrarti per scrivere nel forum
31 risposte