The first time to write a blog, this is the first time to dedicate to my dear MFC ~ As an MFC beginner, I know that you are a beginner classmate friends are not easy, on-line about from the MFC 0 Foundation to explain the MFC books are not many, here on my practice of this small program as far as possible to do the detailed explanation, Please the Friends of the students a lot of guidance, learn from each other, master do not spray ~
The final applet runs as shown in the figure below (the mathematical algorithm for the position of each point of the clock can be computed by itself using the sine cosine theorem or by referring to other people on the Internet):
Well, on the subject, the author of this MFC small program is written with VS2012, so we first step open VS2012, click "File-New project" To create a new project, and select the MFC template, here we will name the project " Clockshower ":
In the pop-up wizard, we don't have to rush to click "Done", click "Next" to go to the next interface, in the application type, we choose the application type "single document", others can remain the default:
Then click on "Next" (Keep the default configuration on the line), until the "generated class" This wizard interface, we select Cclockshowerview, in the "base class" select CFormView, In this way, Cclockshowerview inherits the properties that allow the dialog box control to be dragged to the view view, and we can use the dialog's controls in a single document program:
OK, ready to work, click "Done" to build the project.
Once the project is built, we run it first and get the following interface:
Here to friends and classmates to explain the view of the client area and MAINFRM display range limits, because in the view of the drawing and the drawing in the mainframe do not have the same effect, you can try it yourself:
Find the resource view at the bottom left (or click View and Resource View on the menu) to open "Idd_clockshower_form", which is the dialog box that appears in the View view, in the Toolbox, Dialog editor on the right, We can see that at this point the item allows us to drag various controls (if you click on the toolbox and still don't see a list of controls, click the Toolbox and then right-click on the Toolbox tab in the Blanks, reset the toolbox, etc. vs Reset toolbox), we select "Month Calendar control "This control and drag to the dialog box, and then run the program again, how to see a calendar, a little feel it:
For this calendar control, where we don't need to do anything about it, just put it on the side to make a foil, then we find "Menu->idr_mainframe", this is the main menu window in a single document program, the right of our menu "Please type here" Enter our custom menu options and submenu options "Clock Calendar program" and "Start/stop":
OK, after adding the menu item, you have to add a message handler or command message for the menu item, otherwise the menu item will be dimmed and unusable. So we add an event handler for start/Stop right-click, select the command message type first in the pop-up dialog, and select CMainFrame in the Class list on the right (or choose Cclockshowerview). And in the view to be reasonable to draw, here we choose to CMainFrame to explain, and then click "Add Edit" so in MainFrm.cpp we can see one more Cmainframe::onstartorstopcontrol ()
In the same vein, we add the UPDATE_COMMAND_UI message handler for the Start/Stop submenu item, and after we add it, we add the private variable M_start in the CMainFrame class in MainFrm.h, and initialize M_start = TRUE in the MainFrm.cpp constructor and add code to the two command message functions just now:
void Cmainframe::onstartorstopcontrol ()
{
//TODO: Add Command handler code here
if (M_start)
{
// Stop running the clock program by turning off the timer
KillTimer (1);
}
else
{
//start running the clock program by opening the timer
SetTimer (1,1000,null);
}
Drawing enable to identify reverse
M_start =!m_start;
}
void Cmainframe::onupdatestartorstopcontrol (CCmdUI *pcmdui)
{
//TODO: Add command in this update UI handler code
//According to M_ The value of Bdraw sets whether
Pcmdui->setcheck (m_start) is selected;
}
Select Class View, locate and select the CMainFrame class, right-click Property, or locate properties on the right panel, find "message" in the Properties panel, and then find the "wm_timer" message, which is the timer message, click "<add Ontimer> ", you will see vs for the message handler function that we have built a timer in the CMainFrame class OnTimer, the preceding SetTimer (1,1000,null) is to let the program execute OnTimer function every 1 seconds:
Well, the preparation for the message handler is done, and we're going to start building the class. Specification code, easy to maintain, easy to read, the teacher said you understand:))
Here we build two simple classes on the line, one is the clock class Cclock, one is the needle class (hour, minute, seconds) Cneedle, in the solution view we right-click "header File", add-a class to create these two classes
Once you've written your class name, just click "Done".
Similarly add cneedle this class, the completion will find our "header files" and "source files" are more than "Clock.h, Needle.h" and "Clock.cpp, Needle.cpp" The four files, Where. h files are used to define a class or other public structure such as enumerations, structs, etc., we modify the classes in Clock.h and Needle.h to add code:
Clock.h
#pragma once
#include "Needle.h"
//Clock class
CClock
{public
:
CClock (void);
~cclock (void);
Draw the large circle void drawcircle around the clock
(CDC *pdc,int x1,int y1,int x2,int y2);
Draw the various points above the clock
void Draw (CDC *pdc,int nmovetox,int nmovetoy,int ndrawx,int ndrawy);
Create a brush
void CreatePen (int index,int npenstyle,int nwidth,colorref color);
Get the Circle Brush
CPen *getcirclepen ();
Get the key points of the brush
CPen *getkeypointpen ();
Get the other points of the brush
CPen *getpointpen ();
Get the hour hand
cneedle *gethourneedle ();
Get the minute hand
Cneedle *getminuteneedle ();
Get the second hand
Cneedle *getsecondneedle ();
Private:
//hour
cneedle *m_hourneedle;
Minute hand
Cneedle *m_minuteneedle;
Second hand
Cneedle *m_secondneedle;
The brush of the outer circle
CPen m_circlepen;
Key points of the brush
CPen M_keypointpen;
Other points of the brush
CPen m_pointpen;
};
Needle.h
#pragma once
//PIN class
Cneedle
{public
:
cneedle (void);
~cneedle (void);
Create a brush
void CreatePen (int npenstyle,int nwidth,colorref color);
Draw yourself
void Draw (CDC *pdc,int movetox,int movetoy,int drawx,int drawy);
Get your own brushes
CPen *getpen ();
Public:
//brushes
CPen m_pen;
};
Then write the implementation method in their respective CPP files:
Clock.cpp
#include "stdafx.h" #include "Clock.h" #include "Needle.h" cclock::cclock (void) {//Construction hour, minute hand, second hand m_hourneedle = new Cneed
Le ();
M_minuteneedle = new Cneedle ();
M_secondneedle = new Cneedle ();
} cclock::~cclock (void) {//Release member delete (M_hourneedle);
Delete (M_minuteneedle);
Delete (M_secondneedle);
}//Draw a large circle around the clock void CClock::D rawcircle (CDC *pdc,int x1,int y1,int x2,int y2) {pdc->ellipse (x1,y1,x2,y2);} Draw each point above the clock void CClock::D Raw (CDC *pdc,int nmovetox,int nmovetoy,int ndrawx,int Ndrawy) {//Move the plot point to the root point Pdc->moveto (nMo
Vetox,nmovetoy);
Wire Drawing Pdc->lineto (Ndrawx,ndrawy);
}//Create brush, 0 draw circle, 1 draw key, 2 draw other point void Cclock::createpen (int index,int npenstyle,int nwidth,colorref color) {if (index = = 0)
M_circlepen.createpen (Npenstyle,nwidth,color);
else if (index = = 1) m_keypointpen.createpen (Npenstyle,nwidth,color);
else M_pointpen.createpen (Npenstyle,nwidth,color);
}//Get Brush CPen *cclock::getcirclepen () {return &m_CirclePen;} Get the key point of the brush CPen *cclock::getkeypointPen () {return &m_KeyPointPen;}
Get brushes for other points CPen *cclock::getpointpen () {return &m_PointPen;}
Get the hour hand Cneedle *cclock::gethourneedle () {return m_hourneedle;}
Get the minute hand Cneedle *cclock::getminuteneedle () {return m_minuteneedle;} Get the second hand Cneedle *cclock::getsecondneedle () {return m_secondneedle;}
Needle.cpp
#include "stdafx.h"
#include "Needle.h"
cneedle::cneedle (void)
{
}
cneedle::~cneedle (void)
{
}
void Cneedle::createpen (int npenstyle,int nwidth,colorref color)
{
M_pen.createpen ( Npenstyle,nwidth,color);
}
void Cneedle::D Raw (CDC *pdc,int movetox,int movetoy,int drawx,int Drawy)
{
//move to target root point
pdc->moveto ( Movetox,movetoy);
Wire forming
pdc->lineto (Drawx,drawy);
}
CPen *cneedle::getpen ()
{
return &m_Pen;
}
OK, here, the class has been built, you have to instantiate them and call to see the effect, so we go to MainFrm.h to add a private member variable for the CMainFrame class, the code is as follows (including the previous m_start), remember to add # include " Clock.h ", otherwise cclock this class is not recognized:
Private:
//Control the identification of the menu item
bool M_start;
Clock
CClock *m_clock;
Current system time
CTime M_currenttime;
The current hour
int m_hour;
The current second
int m_second;
The current sub-
int m_minute;
At the same time, in order to make the code structure look more neat, we still create a few methods to encapsulate various implementations, try to avoid all the code is written in a function, so we continue to add methods in the MainFrm.h, the code is as follows:
Public:
//output title and clock literal
void Printtext (CDC *pdc,int quarterwidth,int threequarterswidth,int quarterheight, int threequartersheight,int midwidth,int midheight);
Draw the graph of the clock
void Drawclock (CDC *pdc,int quarterwidth,int threequarterswidth,int quarterheight,int Threequartersheight,int midwidth,int midheight);
Draw all the contents of the calendar
void Drawcalendar (CDC *pdc,crect rect);
Initialize data
void Init ();
Then in the MainFrm.cpp CMainFrame this class to write the specific implementation of these methods (that is, the implementation of the clock and calendar drawing of the core code, the code I have added a basic comment, the students friends if you do not understand the words to my message ha, can help a certain help ~)
Initialize data void Cmainframe::init () {m_start = FALSE;
Construct Clock M_clock = new CClock ();
Build the Brush M_clock->createpen (0,ps_solid,3,rgb (255,255,0)) of the outer circle of the clock;
Build the Brush M_clock->createpen (1,ps_solid,3,rgb (0,0,0)) of the clock key point;
Build a brush M_clock->createpen the other points of the clock (2,ps_solid,2,rgb (0,0,0));
Build the brush of the second hand m_clock->getsecondneedle ()->createpen (Ps_solid,2,rgb (255,0,0));
Build the brush of the minute Hand M_clock->getminuteneedle ()->createpen (Ps_solid,4,rgb (0,0,255));
Build the hand-hour brush M_clock->gethourneedle ()->createpen (Ps_solid,6,rgb (0,255,0)); }//Output interface text, based on six directions to determine the clock and text coordinates void CMainFrame::P rinttext (CDC *pdc,int quarterwidth,int threequarterswidth,int Quarterheight,int threequartersheight,int midwidth,int midheight) {//Get current system time, pass to M_currenttime this->m_
CurrentTime = Ctime::getcurrenttime ();
The formatted time string is CString str = this->m_currenttime.format ("%h:%m:%s");
Set the title font for Microsoft ya Black CFont titlefont; TITLEFONT.CREATEFONTW (35,15,0,0, Fw_normal,false, False,false, Default_charseT,out_device_precis, Clip_default_precis, Default_quality,default_pitch, _t ("Microsoft Jas Black"));
Select the newly created font pdc->selectobject (&titlefont);
Output title PDC->TEXTOUTW (midwidth-180,40,_t ("Welcome to the Clock Calendar simulator"));
Set the font for Microsoft ya Black CFont font; Font. CREATEFONTW (20,7,0,0, Fw_normal,false, False,false, Default_charset,out_device_precis, CL
Ip_default_precis, Default_quality,default_pitch, _t ("Microsoft Jas Black"));
Select the newly created font pdc->selectobject (&font);
The output time of the text PDC->TEXTOUTW (MIDWIDTH-30,MIDHEIGHT+QUARTERHEIGHT+20,STR);
Output weekday CString Clockweek (_t ("Week"));
Int week = M_currenttime.getdayofweek ();
CString Weekstr;
Switch (week) {case 1:weekstr + = _t ("Day"); clockweek+=weekstr;break;
Case 2:weekstr + = _t ("one"); clockweek+=weekstr;break;
Case 3:weekstr + = _t ("II"); clockweek+=weekstr;break;
Case 4:weekstr + = _t ("three"); clockweek+=weekstr;break;
Case 5:weekstr + = _t ("four"); clockweek+=weekstr;break; Case 6:weekstr + = _t ("five"); clockweek+=weekstr;break;
Case 7:weekstr + = _t ("VI"); clockweek+=weekstr;break;
Default:break;
} PDC->TEXTOUTW (Midwidth-25,midheight+quarterheight+40,clockweek); }//Draw the clock to determine the clock coordinates in six directions void CMainFrame::D rawclock (CDC *pdc,int quarterwidth,int threequarterswidth,int quarterheight, int Threequartersheight,int midwidth,int midheight) {//Replace the brush that draws the outer circle and store the system brush CPen *poldpen = Pdc->selectobject (m_clock-
>getcirclepen ()); Draw Round M_clock->drawcircle (pdc,midwidth-quarterheight,quarterheight,midwidth+quarterheight,threequartersheight
);
Change the Brush Pdc->selectobject (M_clock->getkeypointpen ()) to draw a key point; Draw 12, move the brush to the middle width of the customer area, One-fourth of the height of the place, and then the y-axis extends downward 20 units, the other M_clock->draw (Pdc,midwidth,quarterheight,midwidth,
QUARTERHEIGHT+20);
Draw 6 M_clock->draw (pdc,midwidth,threequartersheight,midwidth,threequartersheight-20);
Draw 3 M_clock->draw (pdc,midwidth+quarterheight,midheight,midwidth+quarterheight-20,midheight); Draw 9 M_clock->draw (PDc,Midwidth-quarterheight,midheight,midwidth-quarterheight+20,midheight); Draw 1 M_clock->draw (pdc,midwidth+quarterheight/2,midheight-(int) (0.866* (double) quarterheight), midwidth+
quarterheight/2-10,midheight-(int) (0.866* (double) quarterheight) +17); Draw 7 M_clock->draw (pdc,midwidth-quarterheight/2,midheight+ (int) (0.866* (double) quarterheight),
midwidth-quarterheight/2+10,midheight+ (int) (0.866* (double) quarterheight)-17); Draw 2 M_clock->draw (pdc,midwidth+ (int) (0.866* (double) quarterheight), midheight-quarterheight/2,midwidth+ (int) (
0.866* (double) quarterheight) -17,midheight-quarterheight/2+10); Draw 8 M_clock->draw (pdc,midwidth-(int) (0.866* (double) quarterheight), midheight+quarterheight/2,midwidth-(int) (
0.866* (double) quarterheight) +17,midheight+quarterheight/2-10); Draw 4 M_clock->draw (pdc,midwidth+ (int) (0.866* (double) quarterheight), midheight+quarterheight/2,midwidth+ (int) (
0.866* (double) quarterheight) -17,midheight+quarterheight/2-10); Draw M_clock->draw (Pdc,midwidth-(int) (0.866* (double) quarterheight), midheight-quarterheight/2,midwidth-(int) (0.866* (double) quarterheight) +17,
MIDHEIGHT-QUARTERHEIGHT/2+10); Draw 5 M_clock->draw (pdc,midwidth+quarterheight/2,midheight+ (int) (0.866* (double) quarterheight), midwidth+
quarterheight/2-10,midheight+ (int) (0.866* (double) quarterheight)-17); Draw One M_clock->draw (pdc,midwidth-quarterheight/2,midheight-(int) (0.866* (double) quarterheight),
midwidth-quarterheight/2+10,midheight-(int) (0.866* (double) quarterheight) +17);
Change back to System Brush Pdc->selectobject (Poldpen); Draw other dots for (int i=0;i<60;i++) {M_clock->draw (pdc,midwidth+ (int) (Quarterheight*sin (I*PI/30)), midheight-(int) ( Quarterheight*cos (I*PI/30)), midwidth+ (int) (Quarterheight*0.87*sin (I*PI/30)), midheight-(int) (quarterheight*0.87
*cos (I*PI/30));
}//Change to Second hand brush Pdc->selectobject (M_clock->getsecondneedle ()->getpen ());
Pdc->selectobject (&pens); Draw the second hand m_clock->getsecondneedle ()->draw (pdc,midwidth-(int) (quarterheight*0.3*sin (THIS->M_SECOND*PI/30)), midheight+ (int) (Quarterheight*0.3*cos (THIS->M_SECOND*PI/30)), midWidth+ (int) (Quarterheight*0.8*sin (THIS->M_SECOND*PI/30)), midheight-(int) (Quarterheight*0.8*cos (THIS->M_SECOND*PI/30
)));
Change the component pin Brush Pdc->selectobject (M_clock->getminuteneedle ()->getpen ()); Draw the minute hand m_clock->getminuteneedle ()->draw (pdc,midwidth,midheight,midwidth+ (int) (Quarterheight*0.8*sin (2*PI* ( this->m_minute/60.0+this->m_second/3600.0)), midheight-(int) (Quarterheight*0.8*cos (2*PI* (this->m_
minute/60.0+this->m_second/3600.0)));
Change Brush Pdc->selectobject (M_clock->gethourneedle ()->getpen ()); Draw the hour hand m_clock->gethourneedle ()->draw (pdc,midwidth,midheight,midwidth+ (int) (Quarterheight*0.6*sin (2*PI* ( this->m_hour/12.0+this->m_minute/720.0)), midheight-(int) (Quarterheight*0.6*cos (2*PI* (this->m_Hour/
12.0+this->m_minute/720.0)));
Replace the system brush Pdc->selectobject (Poldpen); }//Draw all the contents of the calendar void CMainFrame::D rawcalendar (CDC *pdc,creCT rect) {//-----------------draw the left edge of the calendar rectangle and the number//Calendar rectangle box is two-thirds customer area width int calendarleft = rect.
Width ()/3*2; The top boundary of the calendar rectangle is one-fourth client area height int calendartop = rect.
Height ()/4; The right edge of the calendar rectangle is the rightmost int calendarright = rect of the client area.
Width (); The bottom boundary of the calendar rectangle is the three-fourths height of the customer area, int calendarbuttom = rect.
Height ()/4*3;
Draw Rectangle Box Pdc->rectangle (calendarleft,calendartop,calendarright,calendarbuttom);
/* * The height of the calendar rectangle is divided into 8 parts, the width is divided into 7 parts */int partwidth = (calendarright-calendarleft)/7;
int partheight = (calendarbuttom-calendartop)/8;
int year = M_currenttime.getyear ();
CString Head; int turns CString head.
Format (TEXT ("%d"), year);
Head+=_t ("year");
int month = M_currenttime.getmonth ();
CString Headpart;
Headpart.format (TEXT ("%d"), month);
head+=headpart+_t ("month");
The first day of the week is Sunday, GetDayOfWeek is 1, and so on//cstring cc;
int dayofweak = M_currenttime.getdayofweek ();
int dayofweak = M_currenttime.getday (); Cc.
Format (TEXT ("%d"), dayofweak);
head+=_t ("Week") +cc;
Draw a year in the top of the calendar rectangle PDC->TEXTOUTW (calendarleft-20+ (calendarright-calendarleft)/2-10,calendartop+10,head);
Sets the font color Pdc->settextcolor (RGB (125,0,255));
Draw the week pdc->textoutw in the calendar rectangle (calendarleft+5,calendartop+partheight*1,_t ("Sunday"));
PDC->TEXTOUTW (calendarleft+5+partwidth,calendartop+partheight*1,_t ("Monday"));
PDC->TEXTOUTW (calendarleft+5+partwidth*2,calendartop+partheight*1,_t ("Tuesday"));
PDC->TEXTOUTW (calendarleft+5+partwidth*3,calendartop+partheight*1,_t ("Wednesday"));
PDC->TEXTOUTW (calendarleft+5+partwidth*4,calendartop+partheight*1,_t ("Thursday"));
PDC->TEXTOUTW (calendarleft+5+partwidth*5,calendartop+partheight*1,_t ("Friday"));
PDC->TEXTOUTW (calendarleft+5+partwidth*6,calendartop+partheight*1,_t ("Saturday"));
Sets the font color Pdc->settextcolor (RGB (0,0,0));
The date in the calendar rectangle to draw a specific number of days//current is what day int nowday = M_currenttime.getday ();
Backup int nowdayback = Nowday for the current number of days;
The current is the day of the week int nowweak = M_currenttime.getdayofweek ();
Calculates the number of rows that the current number of days should be in int row; The default is on the first row of row = 1;
if ((nowday-nowweak) >=0) {row = (nowday-nowweak)/7+1;
if (nowday-nowweak)%7! = 0) {row++;
}}//Line number of the backup int rowback = row;
Replace brush CPen *poldpen = Pdc->selectobject (M_clock->getsecondneedle ()->getpen ()); Date Pdc->ellipse (calendarleft+partwidth* (nowWeak-1), calendartop+partheight* (row+1), calendarleft+, circled the current number of days
partwidth* (Nowweak), calendartop+partheight* (row+2));
Replace the system brush Pdc->selectobject (Poldpen);
Line drawing number//Only the current number of days that row pushes forward for (int j=0;j<nowweak;j++) {if (Nowday = = = 0) break;
CString CStr; Cstr.
Format (TEXT ("%d"), nowday--);
PDC->TEXTOUTW (calendarleft+partwidth* (nowweak-j-1) + 5,calendartop+partheight* (row+1), CStr);
}//Current days upward push int R = row-1;
if (r>0) {for (int i=0;i<r;i++) {row--;
if (Nowday = = 0) break;
for (int j=0;j<7;j++) {CString CStr; Cstr.
Format (TEXT ("%d"), nowday--); PDC->TEXTOUTW (calendarleft+partwidth* (7-j-1) + 5,calendartop+partheight* (row+1), CStr);
if (Nowday = = 0) break;
}}}//Current days push down///month remaining days int restday; if (month = = 1| | Month = = 3| | Month = = 5| | Month = = 7| |
Month = = 8| | Month = = 10| |
month = = () {restday = 31-nowdayback; } else if (month = = 2) {//Leap year if (year%4 = = 0&&year%100) | |
(year%400 = = 0))
{restday = 29-nowdayback;
}//Common year else {restday = 28-nowdayback;
}} else {restday = 30-nowdayback;
} for (int i=0;i<restday;i++) {CString CStr; Cstr.
Format (TEXT ("%d"), ++nowdayback);
PDC->TEXTOUTW (calendarleft+partwidth* (nowweak++) + 5,calendartop+partheight* (rowback+1), CStr);
NewLine if (nowweak = = 7) {rowback++;
Nowweak = 0; }
}
}
Remember to add MainFrm.cpp to add these header files, otherwise you will be prompted not to find the corresponding variable or class:
#include "ClockShowerView.h"
#define PI 3.141593
#include "math.h"
Also, because a call to the view's header file has been added to the CMainFrame, the header file needs to be added in ClockShowerView.h:
#include "ClockShowerDoc.h"
Finally, we modify and add the call to Init in the CMainFrame constructor:
CMainFrame structure/destructor
cmainframe::cmainframe ()
{
//TODO: Add member initialization code in this
Init ();
Theapp.m_napplook = Theapp.getint (_t ("Applicationlook"), id_view_applook_vs_2008);
}
Then we start to run the program, after the click on the menu "Clock Calendar Program" submenu item "Start/stop", our clock and our own drawing of the calendar is out ~, our own drawing of the calendar will vary according to the system time changes, Friends can change their own system time to verify that my own drawing of the calendar is correct (the algorithm himself wrote but not how to test, only try to September and October every day no problem, should still be able to:))
Finally, the whole program is attached to the source code, free points ~ more exchanges, more advice ~
http://download.csdn.net/detail/yueya_shanhua/8108625