/ Forside / Teknologi / Udvikling / C/C++ / Nyhedsindlæg
Login
Glemt dit kodeord?
Brugernavn

Kodeord


Reklame
Top 10 brugere
C/C++
#NavnPoint
BertelBra.. 2425
pmbruun 695
Master_of.. 501
jdjespers.. 500
kyllekylle 500
Bech_bb 500
scootergr.. 300
gibson 300
molokyle 287
10  strarup 270
Hvordan laver man et vindue(Frame) i Visua~
Fra : Christian Kristoffer~


Dato : 03-08-02 12:58

Hejsa alle

Jeg er ved at være lidt træt af at eksperimentere med consol programmer, og
vil gerne lidt videre.

Hvordan får jeg lavet en Frame på skærmen, ligesom alle andre
windowsprogrammer gør det ??

Hilsen

Christian



 
 
Anders (03-08-2002)
Kommentar
Fra : Anders


Dato : 03-08-02 23:01

> Hvordan får jeg lavet en Frame på skærmen, ligesom alle andre
> windowsprogrammer gør det ??

New->Win32 app
New->C++ source file

Og der her kode skulle gerne lave et lille vindue til dig:

#include <windows.h>
#define class_name "STD_WIN_APP"

LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrev, PSTR szCmdLine, int
iShow)
{
HWND hwnd;
MSG msg;
WNDCLASS wc;

wc.cbClsExtra = NULL;
wc.cbWndExtra = NULL;
wc.hbrBackground = (HBRUSH)COLOR_BACKGROUND;
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hIcon = LoadIcon(NULL, IDI_WINLOGO);
wc.hInstance = hInstance;
wc.lpfnWndProc = WndProc;
wc.lpszClassName = class_name;
wc.lpszMenuName = NULL;
wc.style = CS_VREDRAW | CS_HREDRAW;

RegisterClass(&wc);

hwnd = CreateWindow(class_name,
"Std Win App",
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
NULL,
NULL,
hInstance,
NULL);

ShowWindow(hwnd, iShow);
UpdateWindow(hwnd);

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

return msg.wParam;
}

LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch(msg) {

case WM_DESTROY:
case WM_CLOSE:
PostQuitMessage(0);
break;
}

return DefWindowProc(hwnd, msg, wParam, lParam);
}


-Anders




Christian Kristoffer~ (03-08-2002)
Kommentar
Fra : Christian Kristoffer~


Dato : 03-08-02 23:04

Tak for svaret.

Det virker også fint, men hvordan hænger de forskellige ting sammen. Kan du
ligge en par kommentarere ind ?
Det virker lidt for avanceret til at jeg lige kan gennemskue det ??

Hilsen

Christian

"Anders" <muhko@msn.com> skrev i en meddelelse
news:3d4bd46d$0$89494$edfadb0f@dspool01.news.tele.dk...
> > Hvordan får jeg lavet en Frame på skærmen, ligesom alle andre
> > windowsprogrammer gør det ??
>
> New->Win32 app
> New->C++ source file
>
> Og der her kode skulle gerne lave et lille vindue til dig:
>
> #include <windows.h>
> #define class_name "STD_WIN_APP"
>
> LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
>
> int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrev, PSTR szCmdLine,
int
> iShow)
> {
> HWND hwnd;
> MSG msg;
> WNDCLASS wc;
>
> wc.cbClsExtra = NULL;
> wc.cbWndExtra = NULL;
> wc.hbrBackground = (HBRUSH)COLOR_BACKGROUND;
> wc.hCursor = LoadCursor(NULL, IDC_ARROW);
> wc.hIcon = LoadIcon(NULL, IDI_WINLOGO);
> wc.hInstance = hInstance;
> wc.lpfnWndProc = WndProc;
> wc.lpszClassName = class_name;
> wc.lpszMenuName = NULL;
> wc.style = CS_VREDRAW | CS_HREDRAW;
>
> RegisterClass(&wc);
>
> hwnd = CreateWindow(class_name,
> "Std Win App",
> WS_OVERLAPPEDWINDOW,
> CW_USEDEFAULT,
> CW_USEDEFAULT,
> CW_USEDEFAULT,
> CW_USEDEFAULT,
> NULL,
> NULL,
> hInstance,
> NULL);
>
> ShowWindow(hwnd, iShow);
> UpdateWindow(hwnd);
>
> while(GetMessage(&msg, NULL, 0, 0)) {
> TranslateMessage(&msg);
> DispatchMessage(&msg);
> }
>
> return msg.wParam;
> }
>
> LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM
lParam)
> {
> switch(msg) {
>
> case WM_DESTROY:
> case WM_CLOSE:
> PostQuitMessage(0);
> break;
> }
>
> return DefWindowProc(hwnd, msg, wParam, lParam);
> }
>
>
> -Anders
>
>
>



Anders (04-08-2002)
Kommentar
Fra : Anders


Dato : 04-08-02 09:09

Ja, ok..

#include <windows.h>
#define class_name "STD_WIN_APP"

Prototype til WndProc, som håndterer de beskeder, der bliver sendt til
vinduet(tastetryk, museklik osv.)
HWND = Handle to Window. Siden man godt kan have flere forskellige vinduer
kørende på samme tid, bruges hwnd til at bestemme, hvilket vindue man fx vil
skrive noget tekst ud til. Bruges også til at bestemme hvilke vinduer der
hører sammen. Du ved nok, hvis der fx kommer en advarselsboks frem, så kan
man ikke bruge vinduet bag den, før man har trykket ok. Hvis advarselsboksen
ikke var sat til at høre til vinduet bag, ville man godt kunne bruge det,
uden at trykke OK.

UINT = unsigned int
WPARAM = Indeholder oplysninger om forskellige beskeder man sender til
vinduet(fx museklik, tastetryk)
LPARAM=Indeholder også oplysninger om beskeder, men her er det fx om musen
bevæger sig, eller om man bruger hjulet på musen osv.
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);

Okay, winapi er ligesom main() i consol

HINSTANCE= Instance betyder tilfælde, og den bruges fordi man godt kan have
ét program kørerde 2 gange
HINSTANCE hPrev =Useless bogus, altid NULL for win32 apps
PSTR(det samme som en string) szCmdLine= Indeholder information om
parametre(fx hvis man kører programmet fra en dos-boks og skriver
program.exe -l -p)
iShow = Indeholder info om vinduets status(minimized, maximized)

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrev, PSTR szCmdLine, int
iShow)
{
HWND hwnd;

MSG=Indeholder beskeder(as above)

MSG msg;

WNDCLASS=Indeholder information om vinduet(cursor, ikon, style osv);

WNDCLASS wc = {0};

//Baggrundsfarve(her vælger jeg grå. vil du have en anden farve skal du
skrive (HBRUSH)GetStockObject(WHITE_BRUSH) fx)
wc.hbrBackground = (HBRUSH)COLOR_BACKGROUND;
//hvilken cursor vinduet skal bruge. Hvis du vil lave lidt sjov, så byt
loadcursor ud med LoadIcon, og vupti, din cursor er et ikon :)
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
//vinduets ikon
wc.hIcon = LoadIcon(NULL, IDI_WINLOGO);
//bare så den ved hvilken parameter den skal bruge til instance
wc.hInstance = hInstance;
//her fortæller vi den hvilken funktion den skal bruge til at tjekke
beskederne med(mere om det senere)
wc.lpfnWndProc = WndProc;
//gir den et navn
wc.lpszClassName = class_name;
//nej, vi har ikke nogen menu. Hvis vi havde en, skulle den stå her
wc.lpszMenuName = NULL;
//vinduets style. Find flere flags på msdn under WNDCLASS. Her vælger jeg at
vinduet skal tegnes igen, hver gang det skifter størrelse(vertikalt og
horitsonalt)
wc.style = CS_VREDRAW | CS_HREDRAW;
//Registrer klassen hoswindows
RegisterClass(&wc);
//Her bliver vinduet lavet. CreateWindow(Klassens navn(samme navn som
ovenover, så ved den nemlig, at den skal bruge den wndclass vi lige har
lavet), vinduets caption, vinduets style(flere i msdn), x-pos på
skærmen(CW_USEDEFAULT lader windows bestemme), y-pos på skærmen, vinduets
width, height, HWND parent(ingen, vinduet her er jo selv parent), menu(vi
har ingen), instance, variabler eller andet der skal med til
wndprocen(ingen))
hwnd = CreateWindow(class_name,
"Std Win App",
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
NULL,
NULL,
hInstance,
NULL);
//VIs vinduet. hwnd indeholder nu al information om vinduet, både wndclassen
og det vi lige har lavet ovenover
ShowWindow(hwnd, iShow);
//Maler vinduet til skærmen
UpdateWindow(hwnd);

//Loopet her kører under hele programmet, og stopper ikke før man quitter
while(GetMessage(&msg, NULL, 0, 0)) {
//Oversætter beskederne til noget man kan forstå
TranslateMessage(&msg);
//Sender beskederne til WndProc.
DispatchMessage(&msg);
}

return msg.wParam;
}
//Så er vi kommet den den funktion, der håndterer beskederne.
UINT(unsigned int) msg = indeholder information om beskeden(museklik osv)
WPARAM og LPARAM as above
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch(msg) {
//Er beskeden WM_DESTROY eller WM_CLOSE?
case WM_DESTROY:
case WM_CLOSE:
//Så quit programmet.. 0 = WM_QUIT, og det får loopet ovenover(det med
GetMessage) til at stoppe
PostQuitMessage(0);
break;
}

return DefWindowProc(hwnd, msg, wParam, lParam);
}

Okay, det var meget på én gang, og kommenteringen gik sikkert også lidt
hurtigt, men det skulle vidst være til at forstå...

-Anders



Niels Erik Danielsen (04-08-2002)
Kommentar
Fra : Niels Erik Danielsen


Dato : 04-08-02 17:09


"Christian Kristoffersen" <_**NOSPAM**_dsl32328@vip.cybercity.dk> wrote in
message news:aihjv7$2ok6

> Det virker også fint, men hvordan hænger de forskellige ting sammen. Kan
du
> ligge en par kommentarere ind ?
> Det virker lidt for avanceret til at jeg lige kan gennemskue det ??

Det program som Anders postede er et Win32 program der laver et tomt vindue
der har den funktion at det kan lukkes igen
Programmet er lavet i 'flad' C, dvs. uden C++ klasser, og bruger direkte de
kald der findes i Windows til at skrive til skærmen, printere og lign. ( De
kaldes 'GDI' funktioner)
Det var den eneste måde at lavede programmer til windows på i midten af
80'erne, nu bruger de fleste klasse bliblioteker til at lave windows
programmer med.
De gamle funktioner har den fordel at de er uafhængige af hvilke biblioteker
som C Compiler leverandøren levere med, da de er en del af operativsystemet,
samt at det giver mulighed for at lave hurtige kørende programmer.
Hvis du vil lære om denne måde at programmere på er 'Programming Windows' af
Charles Petzold biblen.

Men der skal bare skrives meget kode bare for at lave en simpel dialog box.
Derfor bruger de fleste klasse biblioteker, og det der følger med til Visual
C++ er noget der hedder MFC, som er ved at blive afløst af noget der hedder
'WinFrame' som er klasse biblioteket i .NET.
Hvis du bruger Borland builder har den et tilsvarende klassebibliotek VCL.

Der har tidliger været diskussioner på i denne gruppe omkring MFC,VCL etc.
brug evt. Google til at finde dem.




Søg
Reklame
Statistik
Spørgsmål : 177496
Tips : 31968
Nyheder : 719565
Indlæg : 6408491
Brugere : 218887

Månedens bedste
Årets bedste
Sidste års bedste