MFC

From HoerupWiki
Revision as of 12:44, 19 September 2006 by 193.3.1.132 (talk) (VC++ og system interaktion)
Jump to: navigation, search

Debug output

Ofte har man brug for at få lavet noget debug output men en MessageBox() er måske lidt i overkanten og en log fil er måske for besværlig - så til dette formål har VC++ metoden OutputDebugString() som skriver til output vinduet i den aktuelle debugger - og er der ingen debugger tilknyttet så skrives dataene ikke.

Læs mere på Understanding Win32 "OutputDebugString"

Standart Dialogbokse

En almindelig besked laves med MessageBox("besked" [,"titel"] [,options]) hvor at options feltet bruges til at fastlægge hvilke knapper der skal være og om der skal være et ikon.

Lav en ja/nej boks:

int res = MessageBox("Are you sure", "Question", MB_YESNO);
if (res == MB_YES)
...

Af andre standart dialog bokse kan der nævnes:

  • CFileDialog
  • CFontDialog
  • CColorDialog
  • CPageSetupDialog
  • CPrintDialog
  • CFindReplaceDialog

Eksempel:

CString result;
CFileDialog file(true);

if (file.DoModal() == IDOK)
{
  result = file.GetFileName();
}

Custom Dialogbokse

En ny custom dialogbox laves som en alm. boks og når at du skal kalde den, gøres det som med de indbyggede dialogbokse. Læg mærke til at det er ikke nødvendigt at kalde UpdateData() ved afslutning , det sker nemlig automatisk ved kald af OnOK().

Husk at gøre sådan at du kan få fat i din custom dialogs data enten med en getData() function eller at gøre control variablen public.

Data til og fra dialog-controls

I MFC er der to metoder til at udveksle data mellem programkoden og dialogboxens controls. Enten med kald til til nogle control funktioner såsom

GetDlgItemText(IDC_CONTROL, char*);

eller

CButton::GetWindowText(char *);

Den anden måde er at lave en variabel som man bruger til udveksle data mellem control og programkode. Dataene udveksles mellem program og dialogboks når at man kalder funktionen UpdateData(); denne funktion modtager en parameter i form af en boolean som fortæller om data skal fra program til dialogboks eller omvendt;

//Sender data fra variablen til dialogboksen
UpdateData( false );

//Opdaterer variablen med data fra dialogboksen, dvs. brugerens input
UpdateData( true )

File:Mfc1.png

Ændre stilen

Hvis du i programmet har brug for at ændre indstillinger for din dialogbox kan det gøres med ModifyStile (kan f.eks. kaldes fra OnInitDialog() ). (Følgende kode System-menuen til dialogboksen)

this->ModifyStyle(0, WS_SYSMENU);

Controls

Diverse tips til ændring af controls findes på

Ændre control udfra ID

Når at man i VC++ laver programmer med dialogeditoren, kan man i sin kode bruge GetDlgItem() til at hente en reference til et givent control. Læg mærke til at funktionene returnerer en pointer til et CWnd object.

Herefter kan man f.eks. skjule et object med:

GetDlgItem(IDC_HANDLE)->ShowWindow( false );

eller man kan disable det med

GetDlgItem(IDC_HANDLE)->EnableWindow( false );

Hvis at man skal bruge nogle specifikke funktioner for f.eks. en comboboks kan man lave en type cast på pointeren (her fjernes alle elementer fra boksen):

CComboBox *com = (CComboBox*) GetDlgItem(IDC_HANDLE);
com->ResetContent();

Radio button og checkbox

Status på radiobutton og checkbox kan ændres på to måder:

CButton *button = (CButton*) GetDlgItem(IDC_HANDLE);
button->SetCheck(BST_CHECKED);

eller

CheckDlgButton(IDC_HANDLE, BST_CHECKED);

Waiting Cursor

Hvis du har brug for at vise timeglasset så længe at en bestemt function kører kan du erklære en variabel af typen CWaitCursor i starten af din funktion.

Strenge

MFC har bygget al håndteringen af tekststrenge ind i classen CString, hvilket er noget nemmere at arbejde med end char arrays; f.eks. er det helt legalt at bruge == til at se om to strenge er identiske. Ligeledes kan man bruge = til tildeling og += til at tilføje. Strengens længe kan aflæses med CString::GetLength()


Formaterede strenge

Hvis du har brug for at formatere en streng, kan du bruge CString::Format() som virker på nogen lunde samme måde som standart C funktionen sprintf().

int time,minut,sekund;
CString tid;
...
tid.Format("%d:%d:%d", time, minut, sekund);


Konvertering

CString kan konveretes til andre typer direkte vha.:

CString t = "test";
someLowLevelFunction( (LPCTSTR) t );

eller

CString t = "test";
someLowLevelFunction( (char *) t );

Sockets

Her er nogle korte eksempler på hvordan at man kan arbejde med winsockets ... vær opmærksom på at man bør tjekke returværdien for alle kaldene for at finde ud af hvorvidt at kaldet var problemfrit !

Hvis du f.eks. vil have besked, når at der at der kommer data ind på socket'en, kan du lave en klasse som arver fra CAsyncSocket og implementere OnAccept(), OnConnect(), OnClose(), OnRecieve() eller OnSend()

Server

Dette er en simpel echo server:

char buf[1024];
int status;

int listenPort = 4000;
CAsyncSocket socket;
CAsyncSocket workSocket;
socket.Create(listenPort);
socket.Listen();
while (1) {
  socket.Accept(workSocket);
  status = workSocket.Recieve(buf, 1023); //status indeholder antallet af læste bytes, eller SOCKET_ERROR
  if (status != SOCKET_ERROR) {
    workSocket.Send(buf,status);
  }
  workSocket.Close();
}

Client

Og en tilhørende klient

CString message = "besked";
int status,len;

CAsyncSocket socket;
socket.Create();
socket.Connect("localhost", 4000);
len = message.GetLength();
status = socket.Send(LPCTSTR(message), len); //status indeholder antallet af sendte bytes eller SOCKET_ERROR

VC++ & Serielle porte


MFC tråde

CWorkerThread implementation

VC++ configuration

Linker Errors, CString, ATL, MFC, and YOU!

MFC Includes

Hvis du starter et nyt win32 projekt og har brug for MFC, så skal du includere afxwin.h ogt sørge for at dit project er sat til at må bruge MFC dynamic eller static link libraries.

Extra include dirs

Ekstra include directories angives i projekt properties vinduet -> C/C++ -> General -> Additional include directories (står sikkert øverst)

Extra link libraries

Extra libraries angives i project properties -> Linker -> Input -> Additional Dependencies (øverst). Dette skal sikkert kombineres med project properties -> Linker -> General -> Additional Library Directories (nederst).

Fatal error C1010

Hvis du importerer noget kode (eller skriver selv) som er standart c++ - kan du risikere at du får fejlen "fatal error C1010: unexpected end of file while looking for precompiled header directive".

Dette er fordi at VC++ tror at den skal bruge precompiled headers for at compilere filen, men højst sandynligt skal den ikke dette så derfor skal det disables.

Dette gøres ved at vælge properties for filen der fejler i solution exploreren, finde precompiled headers sektionen og sætte "Create/use precompiled headers" = "Not using precompiled headers"

VC++ og system interaktion

Registrerings-databasen

Kommunikation med registreringsdatabasen foregår i MFC via klassen CRegKey.

Her er et eksempel på brugen af denne klasse : http://www.netalive.org/codersguild/posts/2088.shtml

WMI

System info kan trækkes via WMI interfacet som er baseret på COM/DCOM.

WMI interfacet kan afprøves med værktøjet wbemtest.exe (DCOM indstillinger kan justeres med dcomcnfg.exe)

Active Directory

Data fra et A/D kan trækkes / manipuleres via Active Directory System Interface

Credentials

I winXP/2003 er der tilføjet et ny API til credential håndthering - how to prompt for a password

VC++ og PostgresSQL

libpq

PostgreSQL's standard C interface hedder libpq.

En almindelig libpq kan bygges ifølge instruktionerne.

Hvis at du skal bygge libpq med SSL/TLS support er det nemmeste at hente en openssl binary og installere denne - Dernæst skal du ændre %postgresqldir%\src\interfaces\libpq\win32.mak og tilføje

/I "pathtossl\include"

til CPP_PROJ sektionen, og til LINK32_FLAGS tilføjes der

/LIBPATH:"pathtossl\lib\vc\static"

libpqxx

Vil du derimod hellere have et C++ interface kan man bruge libpqxx.

win32/INSTALL.txt

libpqxx and VC++