Captain's Universe Home
Captain's Universe Home
Cosmic Ray Muon DetectorTeleGarden Pages
Time on MarsBryophyllum Plants
Jupiter Radio AstronomyAncient Pages
Salzburg Tourist GuideEarth Magnetometer
  H O M E     AJAX & MORE     LINUX & MORE     RTAI     XENOMAI     ADEOS IPIPE      
    JAVA & BROWSERS     *NIX     ELECTRONICS     REVIEWS     ARTEMIA     FAIRY SHRIMP      

Captain's VC++ LOG:

This is not a tutorial. But wait! This is my log, started when I was seriously beginning to do VC++. You might find the one or another hint here - some topics are hard to find on the net.

Adding a control to a MFC (Doc/View) App

List Control
Calendar Control
How to print integers
How to display a text in an 'edit box'
Call a method in Doc from View
Slider Control: CSliderCtrl
Progressbar: CProgressBar (Progressbar Control 6.0) (Active-X)
Combo Control (Dropdown)
how to return an array from a function

Radio Bottons: (grouping and checking/unchecking during runtime)
Registry: (reading writing)
Making a static control clickable: (basic hyperlink)
Getting the date / time
Ellipse with transparent filling (draw a filled ellipse with a NULL brush)
Pens, Brushes, filling and text-color
Opening and reading from a file
Useful stuff (strings, numbers etc...)

###################################################################################

Adding a control to a MFC (Doc/View) App: (made with File -> New -> MFC Appwizard (exe) )

0. Go to the graphical dialog editor

1. If the control you want is not in the small controls-window (with the small symbols like arrow, checkbox, radio-button) go to the menu Project / Add to project / Components and controls

2. Add the control to your dialog (select a control in the small controls-window and then 'draw' it in your resource/dialog window

3. Click on the new control, open the wizard with CTRL+W. Go to the 'Message-Maps'-tab, select the class-name where you want to add the control-methods and double-click on the message (Messages) you want. Name the new method.

4. Click on the 'member-variables' tab (be sure you're in the right class (Class name)), select the new control (Control ID's) and click on add variable.
Name the variable, select a category and variable type. i.e. if you have an edit box and you simply want to write into it, select 'value' for the category. So you can simply assign a value to the edit box which is displayed. If you want to access methods or properties of the control you want a 'control' as category.
Variable type: i.e. edit box: you can select all sort of variable types like int, CString etc.
But it is not uncommon that there is only one choice. i.e. CSliderCtrl.

top

###################################################################################

List control: (ya know, the stuff that looks like a table in excel or the right part of windows-explorer)

Add a CListCtrl and associate a member-variable (m_listctrl) to it.
Add this code to your construction section:

LV_COLUMN listColumn;
LV_ITEM listItem;
char* arCol[3] = { "Column 1", "Column 2", "Column 3" };
listColumn.mask = LVCF_FMT|LVCF_WIDTH|LVCF_TEXT|LVCF_SUBITEM;
listColumn.fmt = LVCFMT_LEFT;
listColumn.cx = 160;
for( int nColumn = 0; nColumn < 3; nColumn++ ) {
listColumn.iSubItem = nColumn;
listColumn.pszText = arCol[nColumn];
m_listctrl.InsertColumn( nColumn, &listColumn );
}
// Add list items
listItem.mask = LVIF_TEXT;
listItem.iSubItem = 0;
char* ar1[3] = { "0 / 0", "0 / 1", "0 / 2" };
char* ar2[3] = { "1 / 0", "1 / 1", "1 / 2" };
char* ar3[3] = { "2 / 0", "2 / 1", "2 / 2" };
for( int nItem = 0; nItem < 3; nItem++ ) {
listItem.iItem = nItem;
listItem.pszText = ar1[nItem];
m_listctrl.InsertItem( &listItem );
m_listctrl.SetItemText( nItem, 1, ar2[nItem] );
m_listctrl.SetItemText( nItem, 2, ar3[nItem] );
}

// add this for full row selection
ListView_SetExtendedListViewStyle (m_listctrl.m_hWnd, LVS_EX_FULLROWSELECT);

How to read a selected value:
Within the 'BN_CLICKED' message handler you can use this:

int nSel = m_listctrl.GetNextItem( -1, LVNI_SELECTED );
AfxMessageBox(m_listctrl.GetItemText ( nSel, 0 ));


Simple adding a row to the list control:
In general see the construction code above.
However VC++ can be a real pain in the a..
If you want to set a CString into a row-item, see listItem.pszText below. We have to do some casting,
otherwise the compiler cries.

LV_ITEM listItem;
listItem.mask = LVIF_TEXT;
listItem.iSubItem = 0;
listItem.iItem = rownumber;
listItem.pszText = (char*)(LPCTSTR)(szMsg);
m_listctrl.InsertItem( &listItem );
m_listctrl.SetItemText( rownumber, 1, "-" );
m_listctrl.SetItemText( rownumber, 2, "*" );

For more info go to the MSDN:
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vcmfc98/html/_mfc_clistctrl.asp

top

###################################################################################

Calendar Control 8.0 (Active-X)

Adding a Calendar Control is very easy.
Add the 'Calendar Control 8.0' to your dialog.

Message maps: i.e. 'Click'.

In the 'OnClick' method do stuff like this:

int day = m_cal.GetDay();
int month = m_cal.GetMonth();
int year = m_cal.GetYear();

top

###################################################################################

How to print intergers:

If you want to have an integer as string you must convert it. Otherwise you get just a garbled 'value'.

int intval = 1234;
CString text;
szMsg.Format("value = %d", intval);
// do something with it:
// I usually use this below for debugging
//
or display the value in the statusbar
AfxMessageBox(szMsg);

top

###################################################################################

How to display a text in an 'edit box':

Simple!
Add the 'edit box' control to your dialog.
In the wizard: Add a member variable m_textout: Category 'value' and Variable type 'CString'.
Of course we only do outputs in the View!

If you want to set the text of the edit box, just do this:
CString msg;
m_out = msg;
UpdateData(FALSE); // IMPORTANT: otherwise the value doesn't show up.

You can of course display other data aswell. Just select another variable type (wizard -> member-variable).

top

###################################################################################

Call a method (function) in Doc from View:

CRomeDoc *pDoc = GetDocument();
ASSERT_VALID(pDoc);

int value = pDoc->method();

top

###################################################################################

Slider Control: CSliderCtrl

Add the splider to your dialog.
Add a member variable of category 'control' and variable type 'CSliderCtrl.
Add a message (wizard -> Message Maps) for NM_CUSTOMDRAW (called when the slider is moving and the mouse-button is still pressed) and/or NM_RELEASEDCAPTURE (called when the slider was moved and the mouse button was released).

Get the position with: int pos = m_sliderctrl.GetPos();

Initializing of the slider:
m_sliderctrl.SetRange( int slidermin, int slidermax );
m_sliderctrl.SetTicFreq( int step );

MSDN:
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vcmfc98/html/_mfc_csliderctrl.asp

top

###################################################################################

Progressbar: CProgressBar (Progressbar Control 6.0) (Active-X)

see Slider Control. (note: there are no messages, since it is a passiv control)

m_Progress.SetRange(m_nLower,m_nUpper);
m_Progress.SetStep(m_nStep);
m_Progress.SetPos(m_nLower);

top

###################################################################################

Combo Control (Dropdown - Drop list - Droplist):

Add a Combo Box to your dialog. Add a member variable (Control) to it.
You add a message ( i.e. CBN_SELCHANGE for a message when the value in the dropdown changed)
and add this to your message-function:

UpdateData(TRUE);

To get the current selection use this:

int idx = m_combohourctrl.GetCurSel(); // remember: UpdateData(TRUE) before!

or if you don't want the index, but the text of the current selection:

CString str;
int idx = m_combohourctrl.GetCurSel();
if( idx < 0 ) return;

m_combohourctrl.GetLBText( idx, str );

// now you can use int intvalue = atoi(str) ot float fvalue = atof(str)
// to get the numerical value if applicable

CString Out;
Out.Format( "Drop List Selection => index %d\n%s", idx, str );
AfxMessageBox( Out );

To set an initial value of the dropdown, use this:


m_combohourctrl.SetCurSel(0);
UpdateData(FALSE);

or

CString str = "someitemname";
m_DropDown.SelectString(0,str);

Otherwise the dropdown-value is empty by default.

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vclib/html/_MFC_CListBox.asp

top

###################################################################################





Returning an array from a function: (how to return an array from a function)

Something really annoying about C++ is that you can't return an array from a function (method) like one does in Perl or Java. You have to create the array before calling the function, then call the function, passing a pointer to the array. Within the function, the array is filled.

Examples:


void CRomeView::test (int* x) {
x[0] = 21;
x[1] = 10;
}
void CRomeView::test2 (CString* x) { x[0] = "text1";
x[1] = "text2";
}

Calling the function:

int myint[2];
test(myint);
AfxMessageBox( myint[1] );

CString cs[2];
test2(cs);
AfxMessageBox( cs[1] );


After calling the function, we have the 'return' values in the array we created before.

top

###################################################################################

Radio Bottons: (grouping and selecting/deselecting during runtime)

Grouping: Assuming you have 4 radio buttons and you want to make 2 groups. That means, that you can select either one of the first 2 or one of the second 2.
First make sure that the tab-order of all 4 radio buttons is ascending (Menu: Layout / Tab Order).
Then open the properties window of the first radio-button (right click on it -> Properties) and check the Group-checkbox. Make sure the second radio-botton has the Group-box unchecked. Check the Group-box of the third and uncheck the Group-box of the fourth. You see where this is going to.
The first one of a radio-button-group has to be set to 'Group'. All other radio-buttons Group-option is not selected.

Selecting / deselecting:

Just add a group of radiobuttons to your dialog. Group them or not, it's up to you.
Go to the wizard and add a member variable. You can choose between a 'value' and a 'control'.
Note: There is just one member-variable if you have a group!
A 'value' is very neat, since you can directly read the index-value (integer) of the selected button (starts at 0...).
On the other hand you can just check/select a radio-button by assigning a value to it.
i.e. you want to set radiobutton #3 in a group of 5, do this:


m_radio = 2; // remember: counting starts at zero
UpdateData(FALSE); // don't forget this: writes the values to the controls

If you just have a single radio-button:

m_radio = 0; // select the radio-button
m_radio = -1; // deselect the radio-button

If you want to read back the choice of the user, don't forget to do


UpdateData(TRUE); // reads the values from the controls

before using the value (m_radio) somewhere. Just add this in the message handler (BN_CLICKED) for each radio-button.

You can also use this:
m_radioctrl.SetCheck(1); if you prefer a control.

top

###################################################################################

Registry: (reading and writing - be very careful not to screw it up!!!)

Setting a value in the registry:

#include <atlbase.h> // add this to your .h-file

CRegKey key;
DWORD dwvalue= (DWORD)(myinteger);

long nError = key.Create(HKEY_CURRENT_USER, "Software\\CaptainSoft\\myprg");
if(nError == ERROR_SUCCESS) {
// Code here to write values to MyProgram key
key.SetValue( "Hallo Welt", "StringEintrag");
key.SetValue( dwvalue, "DWORDeintrag");
key.Close();
}


key.Create does create and open the key if it doesn't exist yet, or just open it in case it is already in the registry.

Reading from the registry:

CRegKey key;
DWORD dwlat, dwlon;
key.Open( HKEY_CURRENT_USER, "Software\\CaptainSoft\\myprg", KEY_READ);
key.QueryValue( dwlat, "latdir");
key.QueryValue( dwlon, "londir");
key.Close();

top

###################################################################################

Making a static control clickable: (basic hyperlink)

a. Add a static-control text or static-image (bitmap) to your dialog.
Go to the properties (right-click on the control) and either change the text or select the 'type' -> Bitmap and the image (you have to create the bitmap first). Also check the 'notify' option in the properties!
Then go to the wizard (CRTL-W) and add a BN_CLICKED message to the message-map of your static-control. Name the function to be called when the control is clicked.
Now go to the code and change

ON_BN_CLICKED(IDC_LINK, OnLink)
to
ON_STN_CLICKED(IDC_LINK, OnLink)

Now go to the method 'OnLink' and add this:

ShellExecute(NULL, "open", "http://www.url.com", NULL, NULL, SW_SHOWNORMAL);

If your control is a simple text, you can change the appearance to a certain extent in the properties.
i.e. make a small border around it. If your control is a bitmap image, make the test blue and underline it.


b. If you want it more sophisticated and look like a real link, try this in your OnPaint method:


CWnd* wnds;
wnds = GetDlgItem(IDC_HYPERLINK); //get a pointer to the static control
CPaintDC dc2(wnds); // pointer to the device context of the static control
CFont f;
f.CreateFont( 12, // nHeight
0, // nWidth
0, // nEscapement
0, // nOrientation
FW_NORMAL, // nWeight
FALSE, // bItalic
TRUE, // bUnderline <----
0, // cStrikeOut
ANSI_CHARSET, // nCharSet
OUT_DEFAULT_PRECIS, // nOutPrecision
CLIP_DEFAULT_PRECIS, // nClipPrecision
DEFAULT_QUALITY, // nQuality
DEFAULT_PITCH | FF_SWISS, // nPitchAndFamily
_T("MS Sans Serif")); // lpszFacename
CFont *pOldFont = (CFont*)dc2.SelectObject(&f); //select the font
dc2.SetBkMode(TRANSPARENT); // we want to draw without background
dc2.SetTextColor(RGB(0,0,255)); //set the text-color to blue
CString xx;
m_hyperlink.GetWindowText(xx); //get the text of the hyperlink
//you must assign a member control variable to your static
dc2.TextOut(0, 0, xx); //(over)write the text in the static control
dc2.SelectObject(pOldFont);

Of course you have to make to changes mentioned in a. aswell.

top

###################################################################################

Getting the date / time:

int curday = COleDateTime::GetCurrentTime().GetDay();
int curmonth = COleDateTime::GetCurrentTime().GetMonth();
int curyear = COleDateTime::GetCurrentTime().GetYear();
int curhour = COleDateTime::GetCurrentTime().GetHour();
int curminute = COleDateTime::GetCurrentTime().GetMinute();


http://msdn.microsoft.com/library/default.asp?url=/library/en-
us/vclib/html/_MFC_COleDateTime.3a3a.GetCurrentTime.asp


top

###################################################################################

Ellipse with transparent filling (draw a filled ellipse with a NULL brush):

Ellipse (circles) are filled with the current brush by default. So you have to set the current brush to a NULL_BRUSH to get an 'empty' ellipse/circle:

CBrush* pOldBrush = (CBrush*)dc.SelectObject(GetStockObject(NULL_BRUSH) );
CRect rcEllipse( 10,10,200,200 );
dc.Ellipse( rcEllipse );

top

###################################################################################

Pens, Brushes, filling and text-color:

Here you see how to create a colored pen for drawing, a colored brush for filling and how to set the text-color for TextOut:

// do some init
CPen penblue( PS_SOLID, 0, RGB(0,0,240)); //make the pen

LOGBRUSH logBruGreen;
logBruGreen.lbStyle = BS_SOLID;
logBruGreen.lbColor = RGB(0, 170, 0);
logBruGreen.lbHatch = HS_CROSS;
CBrush brugreen;
brugreen.CreateBrushIndirect(&logBruGreen); //make the brush

//main: selecting the objects for drawing

dc.SelectObject( &penblue ); //select the blue pen, i.e. in a loop

dc.SelectObject(&brugreen); //select the green brush, i.e. in a loop

dc.SetTextColor(RGB(0,0,240)); //set the text-color
//do this when you want the text with a transparent background
dc.SetBkMode(TRANSPARENT);
dc.TextOut( xcoordinate, ycoordinate, somecstringtext);


CPen: http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vcmfc98/html/_mfc_cpen.asp
CBrush: http://msdn.microsoft.com/library/default.asp?url=/library/en-us/wcemfc/htm/cbrush.asp
CDC: http://msdn.microsoft.com/library/default.asp?url=/library/en-us/wcemfc/htm/cdc.asp


top

###################################################################################

Opening and reading a file:

char buf[200];
ifstream fin("captain.txt");
fin.seekg(0, ios::beg);
while (!fin.eof()) {
fin.getline(buf,200);
// do something with buf
}
fin.close();

You need to include #include "fstream.h" !!

top

###################################################################################

Useful stuff :

char buf[200];
int i = strstr(buf, "somestring"); // see if "somestring" is in buf
// -> returns NULL if not found, otherwise the position of somestring

char buf2[2];
int i = atoi(buf2); // makes an integer out of buf2 (array)


char buf4[4];
double dub = atof(buf4); // makes an double out of buf4 (array)


last update: 05-MAR-2003
Google
 
Web www.captain.at
go to top
© 1996-2010 . All rights reserved.
No reproduction, distribution, publishing or transmission of the copyrighted materials at this site is permitted. Policy
go to top