0x1 项目介绍
字母区写上一段字母 大小在50个以内, 可以自己定义,缓冲区每次只能有一个字母, 4个编辑框可以分别吃字母,最后4个吃货的所有字母加起来等于输入的字母和
0x2 难点
多种线程控制的结合使用, 缓冲区的控制, 吃货区的控制
0x3 项目展示
0x4 项目代码
// 20180102_01.cpp : Defines the entry point for the application.
//
#include "stdafx.h"
#include "resource.h"
#include <stdio.h>
HANDLE hMainThread;
HWND hEditBuffer1;
HWND hEditBuffer2;
HWND hEditResource;
HWND hEditEatA;
HWND hEditEatB;
HWND hEditEatC;
HWND hEditEatD;
TCHAR ResString[50]={0};
int ResLength=0;
HANDLE hResEvent_Buffer;
HANDLE hResEvent_Eat;
CRITICAL_SECTION cs_res;
CRITICAL_SECTION cs_buffer;
int GetResChar=0;
int GetBufferChar=0;
int nBufferIndex = -1;
DWORD WINAPI EatThread(
LPVOID lpParameter // thread data
)
{
TCHAR BufferStr[50]={0};
TCHAR EatStr[50]={0};
HWND hEditEat[4] = {hEditEatA,hEditEatB,hEditEatC,hEditEatD};
int nIndex = (int)lpParameter;
while(GetBufferChar<=ResLength)
{
//EnterCriticalSection(&cs_buffer);
WaitForSingleObject(hResEvent_Eat,INFINITE);
EnterCriticalSection(&cs_buffer);
//拿到字符串
if(nBufferIndex==0)
{
//从buffer1中拿
memset(BufferStr,0,50);
memset(EatStr,0,50);
GetWindowText(hEditBuffer1,BufferStr,50);
if(strlen(BufferStr)==0)
{
LeaveCriticalSection(&cs_buffer);
SetEvent(hResEvent_Buffer);
continue;
}
GetWindowText(hEditEat[nIndex],EatStr,50);
int nEatLength = strlen(EatStr);
EatStr[nEatLength] = BufferStr[0];
//设置编辑框
SetWindowText(hEditEat[nIndex],EatStr);
SetWindowText(hEditBuffer1,"");
}else
{
//从buffer2中拿
memset(BufferStr,0,50);
memset(EatStr,0,50);
GetWindowText(hEditBuffer2,BufferStr,50);
if(strlen(BufferStr)==0)
{
LeaveCriticalSection(&cs_buffer);
SetEvent(hResEvent_Buffer);
continue;
}
GetWindowText(hEditEat[nIndex],EatStr,50);
int nEatLength = strlen(EatStr);
EatStr[nEatLength] = BufferStr[0];
//设置编辑框
SetWindowText(hEditEat[nIndex],EatStr);
SetWindowText(hEditBuffer2,"");
}
GetBufferChar++;
LeaveCriticalSection(&cs_buffer);
SetEvent(hResEvent_Buffer);
//LeaveCriticalSection(&cs_buffer);
}
return 0;
}
DWORD WINAPI BufferThread(
LPVOID lpParameter // thread data
)
{
TCHAR BufferStr[50]={0};
HWND hEditBuffer[2] = {hEditBuffer1,hEditBuffer2};
int nIndex = (int)lpParameter;
while(GetResChar<=ResLength)
{
WaitForSingleObject(hResEvent_Buffer,INFINITE);
EnterCriticalSection(&cs_res);
if(nIndex==0)
{
nBufferIndex=0;
}else{
nBufferIndex=1;
}
memset(BufferStr,0,50);
GetWindowText(hEditBuffer[nIndex],BufferStr,50);
//如果=1,不要继续拿了
if(strlen(BufferStr) == 1)
{
LeaveCriticalSection(&cs_res);
SetEvent(hResEvent_Eat);
continue;
}
if(GetResChar==0)
{
//sprintf(BufferStr,"%c",ResString[GetResChar]);
BufferStr[0] = ResString[GetResChar];
SetWindowText(hEditBuffer[nIndex],BufferStr);
GetResChar++;
LeaveCriticalSection(&cs_res);
SetEvent(hResEvent_Eat);
continue;
}
int nLength = strlen(BufferStr);
BufferStr[nLength] = ResString[GetResChar];
SetWindowText(hEditBuffer[nIndex],BufferStr);
GetResChar++;
Sleep(500);
LeaveCriticalSection(&cs_res);
SetEvent(hResEvent_Eat);
}
return 0;
}
DWORD WINAPI MainThreadProc(
LPVOID lpParameter // thread data
)
{
//分别进入两个缓冲区
memset(ResString,0,50);
GetWindowText(hEditResource,ResString,50);
//sprintf(MyBuffer,"%c",strBuffer[1]);
//MessageBox(NULL,MyBuffer,0,0);
//字符串长度
while(ResString[ResLength]!='\0')
{
ResLength++;
}
//实际长度 ResLength+1
HANDLE hBufferThread[2];
hBufferThread[0] = CreateThread(NULL,0,BufferThread,(void*)0,0,NULL);
hBufferThread[1] = CreateThread(NULL,0,BufferThread,(void*)1,0,NULL);
HANDLE hEatThread[4];
hEatThread[0] = CreateThread(NULL,0,EatThread,(void*)0,0,NULL);
hEatThread[1] = CreateThread(NULL,0,EatThread,(void*)1,0,NULL);
hEatThread[2] = CreateThread(NULL,0,EatThread,(void*)2,0,NULL);
hEatThread[3] = CreateThread(NULL,0,EatThread,(void*)3,0,NULL);
hResEvent_Buffer = CreateEvent(NULL,FALSE,TRUE,NULL);
hResEvent_Eat = CreateEvent(NULL,FALSE,FALSE,NULL);
WaitForMultipleObjects(2,hBufferThread,TRUE,INFINITE);
WaitForMultipleObjects(4,hEatThread,TRUE,INFINITE);
CloseHandle(hBufferThread[0]);
CloseHandle(hBufferThread[1]);
CloseHandle(hEatThread[0]);
CloseHandle(hEatThread[1]);
CloseHandle(hEatThread[2]);
CloseHandle(hEatThread[3]);
//关闭事件
CloseHandle(hResEvent_Buffer);
CloseHandle(hResEvent_Eat);
return 0;
}
BOOL CALLBACK MainDialogProc(
HWND hwndDlg, // handle to dialog box
UINT uMsg, // message
WPARAM wParam, // first message parameter
LPARAM lParam // second message parameter
)
{
switch(uMsg)
{
case WM_INITDIALOG:
{
InitializeCriticalSection(&cs_res);
InitializeCriticalSection(&cs_buffer);
hEditResource = GetDlgItem(hwndDlg,IDC_EDIT_RESOURCE);
hEditEatA = GetDlgItem(hwndDlg,IDC_EDIT_EATA);
hEditEatB = GetDlgItem(hwndDlg,IDC_EDIT_EATB);
hEditEatC = GetDlgItem(hwndDlg,IDC_EDIT_EATC);
hEditEatD = GetDlgItem(hwndDlg,IDC_EDIT_EATD);
hEditBuffer1 = GetDlgItem(hwndDlg,IDC_EDIT_BUFFER1);
//SetWindowText(hEditBuffer1,"0");
hEditBuffer2 = GetDlgItem(hwndDlg,IDC_EDIT_BUFFER2);
//SetWindowText(hEditBuffer2,"0");
SetWindowText(hEditResource,"0");
break;
}
case WM_CLOSE:
{
DeleteCriticalSection(&cs_res);
DeleteCriticalSection(&cs_buffer);
EndDialog(hwndDlg,0);
break;
}
case WM_COMMAND:
{
switch(LOWORD(wParam))
{
case IDC_BUTTON_BEGIN:
{
//MessageBox(0,0,0,0);
//开启主线程
hMainThread = CreateThread(NULL,0,MainThreadProc,NULL,0,NULL);
break;
}
}
}
}
return FALSE;
}
int APIENTRY WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
// TODO: Place code here.
DialogBox(hInstance,MAKEINTRESOURCE(IDD_DIALOG_MAIN),NULL,MainDialogProc);
return 0;
}
0x5 总结
写完这个小项目, 自己的印象里面的概念其实还是挺晕乎的, 在写代码控制的时候, 也是不断的尝试, 不断的对线程的条件进行限制。。
最后感觉写挺烂的, 参考下吧
进程就是4GB, 线程就是EIP, 多线程速度快, 不过还是单线程好控制!!