WinAPI Sterowanie wiadomościami w okienkach

0

Mam prostą aplikację testową, przycisk i texBox.

Przyciskiem tworzę obiekt p1.

W jaki sposób mogę wrzucić informację która teraz kierowana jest do cout ( z Open() ) w textBox lub w MessageBox ?

Wiem że do otwierania plików mam OPENFILENAME, ale chodzi mi o to jak z takiego przykładowego obiektu jak ten mój p1 sterować informacjami wrzucanymi do okienek MessageBox, texbox itp.

W przykładach na które się natykam nie doszukałem się takiego połączenia
To moja piaskownica działająca w CodeBlocks.

#include <Windows.h>

#include <fstream>
#include <iostream>

using namespace std;

class Plik
{
private:
    fstream fileStream;
    string SciezkaDoPliku;
    streampos RozmiarPliku;
    streampos WczytanychBajtow;

public:

    Plik(const std::string _SciezkaDoPliku)
        : SciezkaDoPliku{ _SciezkaDoPliku },
        RozmiarPliku{0},
        WczytanychBajtow{0}
    {
        this->SciezkaDoPliku = _SciezkaDoPliku;
        fstream fileStream(SciezkaDoPliku.c_str());
    }



    ~Plik() {
        if (fileStream.is_open()) {
            Close();
        }
    }


    void Close()  //Zamkniecie lacza z plikiem.
        {
        if (fileStream.is_open())
            fileStream.clear();
            fileStream.close();
    }


    int Open() {
        fileStream.open(SciezkaDoPliku.c_str(), ios::in | ios::binary | ios::ate);// proba otwarcia pliku do odczytu
        if (!fileStream.is_open()) {// jesli nie udalo sie otworzyc to ...
            cout << "Nie udalo sie otworzyc pliku." << endl;
            return 1;
        }
        return 0;
    }

};



static HWND button;
static HWND textBoxOutput;

LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);

int CALLBACK WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR cmdLine,int nCmdShow)
{
    HWND hMainWindow;
    WNDCLASS wc = {};
    wc.lpfnWndProc = WindowProc;
    wc.lpszClassName = "Main window class";
    wc.hInstance = hInstance;
    RegisterClass(&wc);


    hMainWindow = CreateWindow(wc.lpszClassName,"Append text main window",WS_OVERLAPPEDWINDOW,CW_USEDEFAULT,CW_USEDEFAULT,500,400,NULL,NULL,hInstance,NULL);

    if(hMainWindow == NULL) return 1;

    button = CreateWindowEx(WS_EX_CLIENTEDGE,"Button","Append",WS_CHILD | WS_VISIBLE | ES_CENTER, 10, 41,75,30,hMainWindow,NULL,NULL,NULL);

    textBoxOutput = CreateWindowEx(WS_EX_CLIENTEDGE,"Edit",TEXT(""),WS_CHILD | WS_VISIBLE | WS_VSCROLL | ES_AUTOVSCROLL |  ES_MULTILINE | ES_READONLY ,10,81,450,150,hMainWindow,NULL,NULL,NULL);


    ShowWindow(hMainWindow,SW_SHOW);

    MSG msg = { };

    while (GetMessage(&msg, NULL, 0, 0))
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }

    return 0;
}

LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    switch(uMsg)
    {
        case WM_COMMAND:
        if((HWND)lParam == button)
        {

            Plik p1("d:\\test1.txt") ;

            // bufor na wiadomosci
            TCHAR* buffer = new TCHAR[150];
            SetWindowText(textBoxOutput,buffer);
            delete [] buffer;
        }
        break;

        case WM_DESTROY:
            PostQuitMessage(0);
            return 0;
    }
    return DefWindowProc(hwnd, uMsg, wParam, lParam);
}

0

Robisz metodę string ReadLine(); w klasie Plik wynosisz Plik p1("d:\\test1.txt") ; poza funkcję jako zmienną głobalną (ewentualnie wewnątrz singleton lub parameters) i sobi używasz, gdzie trzeba.

0
_13th_Dragon napisał(a):

Robisz metodę string ReadLine(); w klasie Plik wynosisz Plik p1("d:\\test1.txt") ; poza funkcję jako zmienną głobalną (ewentualnie wewnątrz singleton lub parameters) i sobi używasz, gdzie trzeba.

Przepraszam, za dużo rzeczy wrzuciłem w ten przykład. Nie chodziło mi o czytanie z pliku. Może uproszczę klasę Plik do takiej postaci:

class Plik
{
private:
    fstream fileStream;
public:

    void Show()
    {
            cout << "Nie udalo sie otworzyc pliku." << endl;
    }
};

bez konstruktora i destruktora z tylko jedną metodą, żeby było prosto.
Chodzi mi o to jak ten komunikat "Nie udalo sie otworzyc pliku." pokazać w textBoxOutput lub w jakimś wyskakującym MessageBoxie
W tym momencie to idzie na konsolę, a ja chciałbym to zobaczyć w textBoxie który mam na oknie.

0

Żeby wysłać coś do kontrolki z poziomu metody Open musiałbyś przekazać jej w parametrze uchwyt okna, ale to IMO słabe rozwiązanie, bo nie widzę powodu, by ta metoda (i ogólnie klasa) wysyłała coś do okien.

Na upartego możesz zrobić klasę bazującą na std::basic_streambuf podpiętą do std::cout/std::cerr, która wysyłałaby komunikaty o błędach do jakiegoś okna z logami.

0
idepozapalki napisał(a):

Wiem że do otwierania plików mam OPENFILENAME

OPENFILENAME nie służy do otwierania plików, to jest struktura przekazywana jako parametr do m.in. GetOpenFileName(), która to funkcja też nie otwiera pliku a tylko wyświetla okno dialogowe do wyboru pliku i zwraca ścieżkę do wybranego pliku w przekazanej strukturze.

Do otwarcia pliku pod WinAPI służy CreateFile.

0
0x666 napisał(a):

Żeby wysłać coś do kontrolki z poziomu metody Open musiałbyś przekazać jej w parametrze uchwyt okna, ale to IMO słabe rozwiązanie, bo nie widzę powodu, by ta metoda (i ogólnie klasa) wysyłała coś do okien.

Na upartego możesz zrobić klasę bazującą na std::basic_streambuf podpiętą do std::cout/std::cerr, która wysyłałaby komunikaty o błędach do jakiegoś okna z logami.

A gdybym chciał wysyłać jakiś dowolny tekst właśnie z poziomu metody Open do tego textBoxOutput.
Jak to zrobić praktycznie w tym przykładzie ?

1

Tak jak pisałem, najprościej (choć nie najlepiej) to przekazać uchwyt:

int Open(HWND hwnd)
{
    fileStream.open(SciezkaDoPliku.c_str(), ios::in | ios::binary | ios::ate); 
    if (!fileStream.is_open()) { 
		SetWindowText(hwnd, TEXT("Nie udalo sie otworzyc pliku.\r\n"));
        return 1;
    }
    return 0;
}

1 użytkowników online, w tym zalogowanych: 0, gości: 1