MFC基本技术

mfc一个类中调用另一个类中的函数
比如Test1类中调用Test2类中的PushInfo()函数
则:((Test2*)theApp.m_pMainWnd)->PushInfo()


对画框点击右键弹出弹出菜单

//复写OnContextMenu

void CStrlenDlg::OnContextMenu(CWnd* pWnd, CPoint point)
{
CMenu menu;
if (!menu.LoadMenu(IDR_MENU1))
{
return;
}
CMenu* pPopupMenu = menu.GetSubMenu(0);
pPopupMenu->TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON, point.x, point.y,pWnd);
}


//状态栏的使用

CStatusBar m_status;
m_status.Create(this);
UINT nID[] = { 10000, 10001 };
m_status.SetIndicators(nID, 2);
m_status.SetPaneInfo(0, 10000, SBPS_NORMAL, 100);//第一个状态栏宽100个像素
m_status.SetPaneInfo(1, 10001, SBPS_STRETCH, 0);

RECT rect = { 0 };
GetClientRect(&rect);
m_status.MoveWindow(0, rect.bottom - 20, rect.right, 20, true);//对应状态栏左上角和右下角的坐标


模态对话框:需要关闭现在打开的对话框才能回到主的对话框
非模态对话框: 不需要关闭现在打开的对话框就能回到主的对话框

非模态对话框的使用方法:

SecondDlg *pDlg = new SecondDlg;
pDlg->Create(IDD_DIALOG, this);
pDlg->ShowWindow(SW_SHOW);

new完指针对象需要删除,删除地方在第二个对话框中的类里复写PostNcDestroy()函数,说明:在销毁窗口后调用。



创建进程的方法:

1、WinExec

WinExec("calc.exe",SW_SHOW);

2、ShellExecute 、ShellExecuteEx

①ShellExecute(NULL, TEXT("Open"), TEXT("1.txt"), NULL, NULL, SW_SHOW);


②SHELLEXECUTEINFO Info;
memset(&Info, 0, sizeof(Info));//结构清0

Info.cbSize = sizeof(Info);
Info.lpVerb = TEXT("open");
Info.lpFile = TEXT("1.txt");
Info.lpParameters = NULL;
Info.fMask = SEE_MASK_NOCLOSEPROCESS;
Info.nShow = SW_SHOWDEFAULT;
ShellExecuteEx(&Info);

3、最经常用的创建进程CreateProcess

//使用两个结构
PROCESS_INFORMATION pi;
STARTUPINFO si;
memset(&si, 0, sizeof(si));
si.cb = sizeof(si);
si.wShowWindow = SW_SHOW;
si.dwFlags = STARTF_USESHOWWINDOW;
::CreateProcess(TEXT("c://windows//system32//calc.exe"),NULL,NULL,FALSE,NULL,NULL,NULL,NULL,&si,&pi);



打开进程和关闭进程

OpenProcess和TerminateProcess


提升进程权限

void RaisePrivileges()
{
HANDLE hToken;
TOKEN_PRIVILEGES tkp;//令牌句柄的权限
tkp.PrivilegeCount = 1;
tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
//打开进程的访问令牌,得到令牌句柄
if(OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &hToken))
{
//得到进程的uid
if (LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &tkp.Privileges[0].Luid))
{
AdjustTokenPrivileges(hToken, FALSE, &tkp, 0x10, (PTOKEN_PRIVILEGES)NULL, 0);
}
}
if (hToken) CloseHandle(hToken);
}



//查找窗口得到窗口句柄,得到进程id,再得到进程句柄
DWORD pid;
//HWND hCalc = ::FindWindow(NULL, TEXT("计算器"));
HWND hCalc = ::FindWindow(TEXT("NotePad"), NULL);
GetWindowThreadProcessId(hCalc, &pid);
RaisePrivileges();
hProc = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);
if (hProc == NULL)
{
AfxMessageBox(L"打开失败");
}
else
{
AfxMessageBox(L"打开成功");
}



通过句柄得到窗口的指针
HWND hWnd = GetSafeHwnd();//获得窗口句柄
CWnd* pWnd = CWnd::FromHandle(hWnd);//当前窗口的指针


获得应用程序主窗口的指针
CStrlenApp* pApp = (CStrlenApp*)AfxGetApp();
CWnd* pMainWnd = pApp->m_pMainWnd;

对窗口的一些操作

//SendMessage(WM_SYSCOMMAND, SC_MAXIMIZE, 0);//最大化
//SendMessage(WM_SYSCOMMAND, SC_MINIMIZE, 0);
//SendMessage(WM_SYSCOMMAND, SC_RESTORE, 0);
//CenterWindow();//窗口显示在中间


::SetWindowPos(m_hWnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);//顶层窗口


//设置程序图标
//HICON hIcon = AfxGetApp()->LoadIcon(IDI___);
//SetIcon(hIcon, FALSE);
//修改标题
SetWindowText(L"ss");




实现过程就是先创建一个进程,然后从进程里读取数据

按钮里的函数实现过程是:


//命令输出用管道,先写入管道,再从管道中读取

//创建管道
HANDLE hPWrite, hPRead;
SECURITY_ATTRIBUTES sa = { 0 };
sa.nLength = sizeof(sa);
sa.bInheritHandle = TRUE;
sa.lpSecurityDescriptor = NULL;


//管道实际上是一块内存
BOOL bCreate;
bCreate = CreatePipe(&hPRead, &hPWrite, &sa, 0);
if (!bCreate)
{
AfxMessageBox("创建管道失败");
}


//创建进程
PROCESS_INFORMATION pi ;
STARTUPINFO si = { 0 };
si.cb = sizeof(si);
//添加连通管道函数
si.hStdInput = GetStdHandle(STD_INPUT_HANDLE);
si.hStdOutput = si.hStdError = hPWrite;//写到管道里了


si.wShowWindow = TRUE;
si.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES;
TCHAR szCmd[MAX_PATH * 2] = {0};
GetDlgItemText(IDC_EDIT1, szCmd, MAX_PATH * 2);
bCreate = CreateProcess(NULL, szCmd, NULL, NULL, TRUE, CREATE_NEW_CONSOLE, NULL, NULL, &si, &pi);
//关闭句柄
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
if (!bCreate)
{
CloseHandle(hPWrite);
CloseHandle(hPRead);
AfxMessageBox("创建失败");
}
else
{
CString str;
CloseHandle(hPWrite);
TCHAR szBuffer[4096];
DWORD dwRead;
while (TRUE)
{
memset(szBuffer, 0, sizeof(szBuffer));
if (!ReadFile(hPRead, szBuffer, 4096, &dwRead, NULL))
break;
str += szBuffer;
SetDlgItemText(IDC_EDIT2, str);
}
CloseHandle(hPRead);
}


创建管道还有进程的过程中写在了构造函数中,点击按钮后直接使用,避免了点击按钮一直创建进程和管道


变化:全局变量TCHAR szCmd[MAX_PATH * 2] = _T("cmd");

添加了一个析构函数。

CpipeDlg::CpipeDlg(CWnd* pParent /*=NULL*/)
: CDialogEx(CpipeDlg::IDD, pParent)
{
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);


//命令输出用管道,先写入管道,再从管道中读取


//创建管道
HANDLE hInWrite, hOutRead;
SECURITY_ATTRIBUTES sa = { 0 };
sa.nLength = sizeof(sa);
sa.bInheritHandle = TRUE;
sa.lpSecurityDescriptor = NULL;


//管道实际上是一块内存
BOOL bCreate;
bCreate = CreatePipe(&m_hInRead, &hInWrite, &sa, 0);
if (!bCreate)
{
AfxMessageBox("创建输入管道失败");
}
bCreate = CreatePipe(&hOutRead, &m_hOUtWrite, &sa, 0);
if (!bCreate)
{
AfxMessageBox("创建输出管道失败");
}
//创建进程
PROCESS_INFORMATION pi;
STARTUPINFO si = { 0 };
si.cb = sizeof(si);
//添加连通管道函数
si.hStdInput = hOutRead;//命令窗口的输入接到输出管道上
si.hStdOutput = si.hStdError = hInWrite;
si.wShowWindow = SW_HIDE;
si.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES;


bCreate = CreateProcess(NULL, szCmd, NULL, NULL, TRUE, CREATE_NEW_CONSOLE, NULL, NULL, &si, &pi);
//关闭句柄
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
if (!bCreate)
{
AfxMessageBox("创建进程失败");
}
CloseHandle(hInWrite);
CloseHandle(hOutRead);


}



void CpipeDlg::OnBnClickedButton1()


{
GetDlgItemText(IDC_EDIT1, szCmd, MAX_PATH * 2);
strcat_s(szCmd, "\n");
DWORD dwBytes;
WriteFile(m_hOUtWrite, szCmd, strlen(szCmd), &dwBytes, NULL);//写文件的方式
Sleep(200);


CString str;
TCHAR szBuffer[4096] = {0};
DWORD dwRead;
while (PeekNamedPipe(m_hInRead,szBuffer,4096,&dwRead,NULL,0) && dwRead  > 0)//PeekNamedPipe查看是不是有数据,有数据的话大于0
{
ReadFile(m_hInRead, szBuffer, dwRead, &dwRead, NULL);
str += szBuffer;
SetDlgItemText(IDC_EDIT2, str);
}




}
CpipeDlg::~CpipeDlg()
{
CloseHandle(m_hOUtWrite);
CloseHandle(m_hInRead);
}





  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值