Miten windows-ikkunassa tulostetaan kuten komentorivillä tämä:
std::cout <<"Hei!";
ja kysytään näin,
int kirjoitus; std::cin >> kirjoitus;
kun windows ikkuna on tällainen?
#include <windows.h> /* Declare Windows procedure */ LRESULT CALLBACK WindowProcedure (HWND, UINT, WPARAM, LPARAM); /* Make the class name into a global variable */ char szClassName[ ] = "WindowsApp"; int WINAPI WinMain (HINSTANCE hThisInstance, HINSTANCE hPrevInstance, LPSTR lpszArgument, int nFunsterStil) { HWND hwnd; /* This is the handle for our window */ MSG messages; /* Here messages to the application are saved */ WNDCLASSEX wincl; /* Data structure for the windowclass */ /* The Window structure */ wincl.hInstance = hThisInstance; wincl.lpszClassName = szClassName; wincl.lpfnWndProc = WindowProcedure; /* This function is called by windows */ wincl.style = CS_DBLCLKS; /* Catch double-clicks */ wincl.cbSize = sizeof (WNDCLASSEX); /* Use default icon and mouse-pointer */ wincl.hIcon = LoadIcon (NULL, IDI_APPLICATION); wincl.hIconSm = LoadIcon (NULL, IDI_APPLICATION); wincl.hCursor = LoadCursor (NULL, IDC_ARROW); wincl.lpszMenuName = NULL; /* No menu */ wincl.cbClsExtra = 0; /* No extra bytes after the window class */ wincl.cbWndExtra = 0; /* structure or the window instance */ /* Use Windows's default color as the background of the window */ wincl.hbrBackground = (HBRUSH) COLOR_BACKGROUND; /* Register the window class, and if it fails quit the program */ if (!RegisterClassEx (&wincl)) return 0; /* The class is registered, let's create the program*/ hwnd = CreateWindowEx ( 0, /* Extended possibilites for variation */ szClassName, /* Classname */ "Windows App", /* Title Text */ WS_OVERLAPPEDWINDOW, /* default window */ CW_USEDEFAULT, /* Windows decides the position */ CW_USEDEFAULT, /* where the window ends up on the screen */ 544, /* The programs width */ 375, /* and height in pixels */ HWND_DESKTOP, /* The window is a child-window to desktop */ NULL, /* No menu */ hThisInstance, /* Program Instance handler */ NULL /* No Window Creation data */ ); /* Make the window visible on the screen */ ShowWindow (hwnd, nFunsterStil); /* Run the message loop. It will run until GetMessage() returns 0 */ while (GetMessage (&messages, NULL, 0, 0)) { /* Translate virtual-key messages into character messages */ TranslateMessage(&messages); /* Send message to WindowProcedure */ DispatchMessage(&messages); } /* The program return-value is 0 - The value that PostQuitMessage() gave */ return messages.wParam; } /* This function is called by the Windows function DispatchMessage() */ LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { switch (message) /* handle the messages */ { case WM_DESTROY: PostQuitMessage (0); /* send a WM_QUIT to the message queue */ break; default: /* for messages that we don't deal with */ return DefWindowProc (hwnd, message, wParam, lParam); } return 0; }
Ikkunan koodi on Dev-C++:sta.
Käyttäjälle tulostettavan tekstin voi sijoittaa vaikka STATIC-tyyppiseen kontrolliin. Syötteen lukeminen on vielä hankalampaa, paras tapa olisi varmaan tehdä EDIT-tyyppinen kontrolli eli tekstilaatikko ja tunnistaa sitten, milloin käyttäjä painaa laatikossa enteriä. Kontrolleja käsitellään WinAPI:ssa kuten ikkunoita.
Eli ei ole helppoa eikä tapahdu ollenkaan samalla tavalla kuin komentorivillä. WinAPI-ohjelmointia en suosittelisi kenellekään, kun muut kirjastot (wxWidgets, Qt, GTK) ovat paljon yksinkertaisempia. Graafista ohjelmointia en suosittele sinulle vielä pitkään aikaan, kun et selvästi osaa oikein alkeitakaan kunnolla.
Metabolix kirjoitti:
Kontrolleja käsitellään WinAPI:ssa kuten ikkunoita.
Siis miten?
Jos nyt välttämättä haluat, voit lukea vaikka jotain WinAPI-opasta. En kuitenkaan usko, että pääset kovin pitkälle, kun et ole vielä opetellut alkeita kunnolla.
Kiitos.
Onko vielä jotain yksinkertaisemmin saatavaa teksti-ikkunaa?
TVdata kirjoitti:
Onko vielä jotain yksinkertaisemmin saatavaa teksti-ikkunaa?
Lähtökohtana on että C++ -kielessä juuri mikään ei ole yksinkertaista. Jos koodauksen helppous kiinnostaa ja haluat saada nopeammin jotain aikaan, niin kannattaa tutustua vaikka Lazarus & Freepascaliin
http://lazarus.freepascal.org/
Enkö juuri hetki sitten luetellut kolmekin helpompaa vaihtoehtoa eli kirjastot wxWidgets, Qt ja GTK? Mutta eivät nekään ole niin paljon helpompia, että sinun kannattaisi niihin koskea. Käytitpä mitä kirjastoa tahansa, alkeet on aivan pakko opetella kunnolla, ennen kuin siitä käyttöliittymästä on paljonkaan iloa.
Jos on aivan hirveä hinku tehdä graafisia tuotoksia, vaikkei osaa vielä mitään, kannattaa kyllä vaihtaa kieltä. Esimerkiksi Pascal (Lazarus-kehitysympäristö), Java (NetBeans-kehitysympäristö) ja C# (Visual C# Express) ovat helpompia vaihtoehtoja.
TVdata kirjoitti:
Kiitos.
Onko vielä jotain yksinkertaisemmin saatavaa teksti-ikkunaa?
Vaikka se konsoli? Siihen voit tulostaa coutilla ja lukea cinillä.
Morjens TVdata!
kokeile lisätä viritelmääsi oheiset pätkät...
//------ tämän rivin jälkeen ---------- #include <windows.h> //------------- näm rivit ------------- #include <tchar.h> #include <string> //------------------------------------- //------------------ tämän rivin jälkeen -------------------- LRESULT CALLBACK WindowProcedure (HWND, UINT, WPARAM, LPARAM); //------------------- nämä rivit ---------------------------- LRESULT CALLBACK EditBoxProc (HWND, UINT, WPARAM, LPARAM); WNDPROC oldEdit; LPCTSTR strMsg = "Kirjoita alla olevaan tekstiruutuun ja paina Enter-näppäintä"; #define IDC_EDIT_BOX 101 HWND hWndEdit1; //------------------------------------------------------------ //... //------------------ tämän rivin jälkeen -------------------- ShowWindow (hwnd, nFunsterStil); //------------------------ nämä rivit ----------------------- hWndEdit1 = CreateWindow("Edit", "", WS_BORDER | WS_CHILD | WS_VISIBLE, 10, 40, 100, 20, hwnd, (HMENU)IDC_EDIT_BOX, NULL, NULL); SetFocus(hWndEdit1); oldEdit = (WNDPROC) SetWindowLong (hWndEdit1, GWL_WNDPROC, (LONG) EditBoxProc); //----------------------------------------------------------- //... LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { //------- tähän alkuun nämä rivit ---------- HDC hDC; PAINTSTRUCT Ps; //------------------------------------------ switch (message) { case WM_DESTROY: PostQuitMessage (0); break; //-------------- tähän kohtaan nämä rivit ----------------- case WM_PAINT: hDC = BeginPaint(hwnd, &Ps); TextOut(hDC, 10, 10, strMsg, _tcslen(strMsg)); EndPaint(hwnd, &Ps); break; //--------------------------------------------------------- default: return DefWindowProc (hwnd, message, wParam, lParam); } return 0; } // ---------------------- ja loppuun nämä rivit ------------------ LRESULT CALLBACK EditBoxProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { char buffer[65536]; std::string str; int txtlen; switch (message) { case WM_KEYDOWN: if (wParam == VK_RETURN) { txtlen = GetWindowTextLength(hWndEdit1) + 1; GetWindowText(hWndEdit1, buffer, txtlen); str = buffer; MessageBox(NULL, str.c_str(), "MsgBox", MB_OK); SetFocus(hWndEdit1); SendMessage(hWndEdit1,EM_SETSEL,txtlen,txtlen); } break; default: break; } return CallWindowProc(oldEdit, hwnd, message, wParam, lParam); }
Selittäisitkö mistä tiedän oikeat paikat?
TVdata kirjoitti:
Selittäisitkö mistä tiedän oikeat paikat?
Jos, et kykene hahmottamaan, että mistä mikäkin asia muodostuu, niin sitten perusohjelmointitaidoissa on niin paljon puutteita, että on turha yrittääkään mitään tuollaista...
Aloita siitä pythonista / C++ perusteista (+ QT ja tee pikkupelejä [tetris tulee olemaan vaikea]). P*skinta p*skaa win32 opettelu tulee oleman ilman perusteellista ymmärrystä edeltävistä aiheista. En tarkoita nyt vain C++ hyvää ymmärrystä.
jimi-kimi kirjoitti:
P*skinta p*skaa win32 opettelu tulee oleman ilman perusteellista ymmärrystä edeltävistä aiheista.
Paskinta paskaa tuo näyttää olevan vaikka perusteellinen ymmärrys ohjelmoinnista onkin.
En ole koskaan Win32 API:lla koodannut, mutta kun katsoo koodia niin mitä vit**a?-fiilis on vahva. Oliko suunnittelu mennyt 80-luvulla pieleen eikä sitä enää voinut kokonaan uudistaa vai mikä lienee?
Enpä mä nyt tiedä onko tuo sen kummallisempaa kuin muillekaan käyttiksille. Sitä vartenhan erilaisia alustoja (Qt, .Net, Java, yms) tehdään, että koodaajan ei tarvitsisi välittää tuon tason apeista.
Sitä paitsi omasta mielestäni Win32 APIlla ohjelmointi ei ole edes kovin konstikasta. Toki jos lyödään läjä koodia eteen, josta ei tiedä miksi siinä tehdään asioita, niin kyllähän se ankealta näyttää.
Plus täytyy muistaa, että tuo on Neaun koodi ja ne näyttää aina oksennuksilta kielestä riippumatta ;D Sori Neau, ei millään pahalla.
No, ehkä kuitenkin pääpointti tässä kohtaan on se, että jos kokeneemmatkaan ohjelmoijat eivät lähtisi suoraan ohjelmoimaan näin matalantason API:lla käyttöliittymiä, niin tuskin kannattaa täysin noviisinkaan ohjelmoida... Yleensä kun lähtee opettelemaan jotain liian mutkikasta, koski se sitten ohjelmointia tai ei, mielenkiinto lopahtaa asiaa kohtaan hetkessä. Sama peruskuvio toistuu aina, kun 12 v. jonne tulee selittämään, että haluaa ohjelmoida 3D-pelin.
Grez kirjoitti:
Plus täytyy muistaa, että tuo on Neaun koodi ja ne näyttää aina oksennuksilta kielestä riippumatta.
Oksennukselta? Oli kieli sitten mikä tahansa, aina ihan samoja funktioiden nimiä siinä on vaan varustettu erilaisilla konstanteilla yms.
ErroR++ kirjoitti:
Grez kirjoitti:
Plus täytyy muistaa, että tuo on Neaun koodi ja ne näyttää aina oksennuksilta kielestä riippumatta.
Oksennukselta? Oli kieli sitten mikä tahansa, aina ihan samoja funktioiden nimiä siinä on vaan varustettu erilaisilla konstanteilla yms.
Mikäköhän tuossa jäi ymmärtämättä? Jos koodaa käyttämällä huonoja koodauskonventioita, niin koodista kuin koodista saa oksennuksen näköistä. On tietenkin kieliä, kuten C++, josta saa kaksikertaa helpommin sekavaa...
Grez kirjoitti:
Sitä paitsi omasta mielestäni Win32 APIlla ohjelmointi ei ole edes kovin konstikasta.
Joo, ei se varmaan mitenkään erityisen hankalaa ole, mutta kyllä koodari-paran pitäisi ainakin hetken olla WTF kun puuttuu standardi main-funktio ja lukee:
int WINAPI WinMain (HINSTANCE hThisInstance, HINSTANCE hPrevInstance, LPSTR lpszArgument, int nFunsterStil)
Itse kävisin kurkkaamassa <windows.h> että mitä kummaa. Ja mitä noi LRESULT CALLBACK ym. ovat.
Ei standardia ole tietenkään pakko noudattaa, mutta olisi ihan kiva tietää mitä tuolla voitetaan.
Vertailu samantason koodiin:
/* Simple Xlib application drawing a box in a window. gcc input.c -o output -lX11 */ #include <X11/Xlib.h> #include <stdio.h> #include <stdlib.h> #include <string.h> int main(void) { Display *d; Window w; XEvent e; char *msg = "Hello, World!"; int s; /* open connection with the server */ d = XOpenDisplay(NULL); if (d == NULL) { fprintf(stderr, "Cannot open display\n"); exit(1); } s = DefaultScreen(d); /* create window */ w = XCreateSimpleWindow(d, RootWindow(d, s), 10, 10, 200, 200, 1, BlackPixel(d, s), WhitePixel(d, s)); /* select kind of events we are interested in */ XSelectInput(d, w, ExposureMask | KeyPressMask); /* map (show) the window */ XMapWindow(d, w); /* event loop */ while (1) { XNextEvent(d, &e); /* draw or redraw the window */ if (e.type == Expose) { XFillRectangle(d, w, DefaultGC(d, s), 20, 20, 10, 10); XDrawString(d, w, DefaultGC(d, s), 50, 50, msg, strlen(msg)); } /* exit on key press */ if (e.type == KeyPress) break; } /* close connection to server */ XCloseDisplay(d); return 0; }
API-kikkailut on nörteille :D Ikkunan luonti Lazaruksella:
ikkuna := TForm.Create;
Tärkeintä lienee, tarvitsetko oikeasti joka kerta kustomoida ikkunan luonnin komento komennolta? WinAPI:n kanssa on niin paljon tavaraa joka toistuu joka kerta. Käyttää dll-funktioita ja sen erikois-vakioita suoraan raakana... Ohjelmoijalle on suunnaton helpotus jos sen saa nidottua yhteen luokkaan joka tekee sen kaiken sun puolesta.
JaskaP:n koodi näyttää jo kätevämmältä, muttei vielä käytä olio-ohjelmoinnin hienouksia.
Niin ja jos haluaa päästä lopustakin mielenterveydestään, niin voihan aina kaivaa sen editorin esiin ja näpytellä kaikki suoraan assemblerille :D
Jotkut sitäkin harrastaa http://www.grc.com/smgassembly.htm
User137 kirjoitti:
JaskaP:n koodi näyttää jo kätevämmältä, muttei vielä käytä olio-ohjelmoinnin hienouksia.
JaskaP:n koodin tarkoitus lienee vain näyttää, että WinAPI on jopa omassa sarjassaan sekava. Xlib-versiossa (eli Linuxin "matalalla tasolla") ohjelman kulku on ilmeinen kenelle tahansa, joka ymmärtää C:stä edes jotain. WinAPI-versio vaatii enemmän taustatietoa mm. siksi, että tietotyypit on nimetty huonosti ja yksinkertainenkin ohjelma käyttää callbackia.
Grez kirjoitti:
...
Plus täytyy muistaa, että tuo on Neaun koodi ja ne näyttää aina oksennuksilta kielestä riippumatta ;...
Grez@ oikein arvasit, se oksennus oli tarkoitettu päällesi...
Minulla ei Windows API:sta hirveästi kokemusta ole, mutta OS/2:n PM ohjelmointi on hyvin samankaltaista. OS/2:n PM ohjelmassa tosin ei tarvita WinMain funktiota ja piirtäminen sekä koordinaatisto on toteutettu hiukan erilailla.
OS/2:n C:llä ohjelmointi on kohtuullisen suoraviivaista valmiiden headereiden ja macrojen kanssa, mikäli ymmärrys toiminnan perusteista on kohtuullisesti hallinnassa.
En tee noilla enää yhtään mitään. En ainakaan halua jotain win-DOSeja applen koneelle edes rinakkaiseksi tilaa vieämään.
Kiitos siis ohjelmointikielistä.
Tämä kannattanee lukea: https://www.ohjelmointiputka.net/koodivinkit/
Olen itse kehittelemässä itselleni pientä kirjastoa ikkunoiden käsittelyyn C++:lla ja projekti on edistynyt. (Olen ymmärtänyt alkeet WinAPI:sta.)
Kyllähän tuossa JaskaP:n koodissakin on kommentti "Event loop". Se vastaa Windows -ikkunan MessageLoop:ia. Mutta onhan tuo paljon yksinkertaisempi.
C++ ohjelmoijalle suosittelisin tutustumaan: C++ materiaalia, mukaan lukien WinAPI tutoriaaleja
Suosittelisin unohtamaan sen WinAPI:n. Siinä ajassa, joka menee WinAPI:n alkeiden oppimiseen, voisi opetella jotain parempaa kirjastoa paljon pidemmälle ja koodata hienompia, vähemmän bugisia ohjelmia.
Aihe on jo aika vanha, joten et voi enää vastata siihen.