MFC当中CClientDC类当中的MoveTo与LineTo的运用

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了MFC当中CClientDC类当中的MoveTo与LineTo的运用相关的知识,希望对你有一定的参考价值。

void CExercise_drawView::OnMouseMove(UINT nFlags, CPoint point)

// TODO: Add your message handler code here and/or call default
CClientDC dc(this);
CPen pen(PS_DASH,0.5,RGB(0,255,0));
CPen* oldpen=dc.SelectObject(&pen);
if(judge==true)
dc.MoveTo(m_point);
dc.LineTo(point);
dc.LineTo(cpoint);

m_point=point;

dc.SelectObject(oldpen);
CView::OnMouseMove(nFlags, point);


在这段代码中我不明白就是那个
dc.MoveTo(m_point);
dc.LineTo(point);
dc.LineTo(cpoint);
这三个之间是怎么搭配的,是第一个做起点,都两个做终点并且分别画两条线

还是“dc.MoveTo(m_point);做起点” ,“dc.LineTo(point);”做终点并且画线 ,然后“dc.LineTo(point);”做起点,“dc.LineTo(cpoint);”做终点并且画线

到底是怎么个搭配呀???

其实可以用中文来翻译。

MOVETO,就是把那个画笔的点,放至m_point坐标。
LINETO,就是从m_point画一条线,到达point.
LINETO,现在,起点就是point了。那么从point出发,画一条线到达cpoint。

明白了吧?
参考技术A moveto 是将光栅起点移动到光标,下一步绘制将从这儿开始
lineto顾名思义,就是从当前光栅起点划线到当前点。连接成一个直线,并且移动光栅点到当前位置。

那么接下来的lineto 就构成了一个线序列。

MFC进程的创建销毁线程的创建与交互

进程的创建

    STARTUPINFO si;   //**成员DWORD   dwFlags;表示结构体当中哪些成员有效。**STARTF_USESHOWWINDOW|STARTF_USEPOSITION
    PROCESS_INFORMATION pi;
    ZeroMemory(&si, sizeof(si));
    si.cb = sizeof(si);
    ZeroMemory(&pi, sizeof(pi));
                         //LPTSTR  pszCmdLine = TEXT("C:\\Windows\\System32\\notedap.exe");改成
                         //TCHAR  pszCmdLine[] = TEXT("C:\\Windows\\System32\\notedap.exe");
                         //Windows核心编程专门有讲这个问题  CreateProcess会修改传递给它的命令行字符串, LPTSTR是字符串指针不能修改....* /    
    //char* szCommandLine ="C:\\Program Files (x86)\\KuGou\\KGMusic\\KuGou.exe";
    TCHAR  szCommandLine[] = TEXT("notepad ReadMe.txt");//父进程当前目录下的ReadMe.txt    
    ::CreateProcess(NULL,//可执行文件名(必须添加.exe。若未添加路径则只会去当前目录找。so一般为NULL)
                   (LPWSTR)szCommandLine,//传递给执行模块的参数,相当于在运行栏输入szCommandLine(可以在一些目录下自动搜寻exe)
                    NULL,//进程安全性
                    NULL, //线程安全性
                    FALSE,//当前进程的可继承句柄是否可以被新进程继承
                    NULL,//创建标志 如 CREAT_NEW_CONSOLE
                    NULL, //环境变量
                    NULL,//当前目录
                    &si,//父给子进程的显示信息
                    &pi);//此进程的标志信息  ID\句柄
    &pi.dwProcessId;//进程ID
    &pi.dwThreadId;//进程中主线程ID
    &pi.hProcess;//进程内核句柄
    &pi.hThread;//进程中主线程内核句柄

终止进程

    //::ExitProcess(0);  //终止当前进程,退出代码0    
    //BOOL bBet=::TerminateProcess(pi.hProcess,-1);//退出代码-1(关闭进程失败)

    HANDLE hProcess = ::OpenProcess(PROCESS_ALL_ACCESS, //想得到的访问权限
                                    FALSE,        //返回的句柄是否可以被继承
                                    pi.dwProcessId);//进程ID
    BOOL bBet = ::TerminateProcess(hProcess, -1);//(关闭进程成功)

    CloseHandle(hProcess);
    CloseHandle(pi.hProcess);  //不使用就关闭

创建线程

    DWORD dwThreadId;
    HANDLE hHandle;
    hHandle = ::CreateThread(NULL,      //线程安全属性
                             NULL,      //线程堆栈大小
                             ThreadFun, //线程函数起始地址
                             NULL,      //传给线程函数的参数
                             0,         //是否立即启动线程
                             &dwThreadId);//取得线程ID
    //一般使用下面方法
    UINT uId;
    HANDLE hHandleCopy;
    hHandleCopy = (HANDLE)::_beginthreadex(NULL,      //线程安全属性
                               NULL,      //线程堆栈大小
                               ThreadProc, //线程函数起始地址
                               NULL,      //传给线程函数的参数
                               0,         //是否立即启动线程
                               &uId);//取得线程ID

线程函数如下:

//============================================================================================
//线程函数的定义
//DWORD WINAPI ThreadFun()     //参数LPVOID IpParam是必须的
DWORD WINAPI ThreadFun(LPVOID IpParam)
{
    STARTUPINFO si;  
    PROCESS_INFORMATION pi;
    ZeroMemory(&si, sizeof(si));
    si.cb = sizeof(si);
    ZeroMemory(&pi, sizeof(pi));
    TCHAR  szCommandLine[] = TEXT("C:\\Program Files (x86)\\KuGou\\KGMusic\\KuGou.exe");
    ::CreateProcess(NULL,(LPWSTR)szCommandLine,NULL,NULL,FALSE,NULL,NULL, NULL,&si,&pi);
    return 0;
}
//=============================================================================================
UINT _stdcall ThreadProc(LPVOID IpParam)
{
    ::WaitForSingleObject(g_hEvent,INFINITE);
    STARTUPINFO si;
    PROCESS_INFORMATION pi;
    ZeroMemory(&si, sizeof(si));
    si.cb = sizeof(si);
    ZeroMemory(&pi, sizeof(pi));
    TCHAR  szCommandLine[] = TEXT("notepad ReadMe.txt");
    ::CreateProcess(NULL, (LPWSTR)szCommandLine, NULL, NULL, FALSE, NULL, NULL, NULL, &si, &pi);
    return 0;
}
//================================================================================================

线程通信交互

    //线程之间的交互(事件内核对象)
    //HANDLE g_hEvent;
    g_hEvent = ::CreateEvent(NULL, //事件对象安全属性
                             FALSE, //是否是手动重置事件对象为未受信(否则系统自动重置)
                             FALSE, //初始状态(受信/未受信)执行中:未受信
                             NULL); //事件对象名称(可用于OpenEvent()函数的第三个参数,类似进程)


    ::WaitForSingleObject(hHandle,     //对象句柄
                          INFINITE);   //等待时间(\毫秒)
    Sleep(10000);
    SetEvent(g_hEvent);
    //RetEvent(g_hEvent); //自动模式下无需重置(自动重置)
    ::WaitForSingleObject(hHandleCopy,INFINITE);  //等待

    //::WaitForMultipleObjects(2,        //对象句柄数量
    //                           h,        //对象句柄数组
    //                           TRUE,     //是否等待所有内核对象变为受信状态(否则有一个就可以)
    //                           INFINITE) //等待时间(\毫秒)
    //很实用,等待指定线程执行完毕(不加这句线程还未执行完毕主线程就已经结束了)

其中SetEvent(g_hEvent);中的g_hEvent是全局变量HANDLE g_hEvent;

SetEvent(g_hEvent)使得事件对象g_hEvent变为受信状态,

此时ThreadProc函数中的::WaitForSingleObject(g_hEvent,INFINITE);函数检测到其为受信时开始执行接下来的代码。

终止线程与终止进程类似,一般不使用终止进程和线程函数,一般使用通信机制告诉要关闭的进程或线程让其自行退出。

强行终止会使得来不及执行析构函数,回收内存,造成内存泄漏。

 

以上是关于MFC当中CClientDC类当中的MoveTo与LineTo的运用的主要内容,如果未能解决你的问题,请参考以下文章

关于MFC中的CClientDC的问题

MFC程序执行过程剖析(转)

MFC 程序入口和执行流程

VC++ 6.0当中,CString和string这两种类型有啥区别?

C++MFC编程笔记day06 MFC向导MFC绘图类使用

6 接口与内部类