📄 form1.h
字号:
public: [DllImport("user32.dll", CharSet = CharSet::Auto,
BestFitMapping = true,CallingConvention = CallingConvention::Cdecl)]
static BOOL IsWindowVisible(IntPtr hWnd);
public: [DllImport("user32.dll", CharSet = CharSet::Auto,
BestFitMapping = true,CallingConvention = CallingConvention::Cdecl)]
static BOOL ClientToScreen(IntPtr hWnd,LPPOINT lpPoint);
public: [DllImport("user32.dll", CharSet = CharSet::Auto,
BestFitMapping = true,CallingConvention = CallingConvention::Cdecl)]
static BOOL GetClientRect(IntPtr hWnd,LPRECT lpPoint);
public: [DllImport("user32.dll", CharSet = CharSet::Auto,
BestFitMapping = true,CallingConvention = CallingConvention::Cdecl)]
static IntPtr GetForegroundWindow();
public: [DllImport("user32.dll", CharSet = CharSet::Auto,
BestFitMapping = true,CallingConvention = CallingConvention::Cdecl)]
static bool EnumDisplaySettings(
__in LPCTSTR lpszDeviceName,
__in DWORD iModeNum,
__out DEVMODE *lpDevMode
);
public: [DllImport("user32.dll", CharSet = CharSet::Auto,
BestFitMapping = true,CallingConvention = CallingConvention::Cdecl)]
static bool EnumDisplayDevices(
__in LPCTSTR lpDevice,
__in DWORD iDevNum,
__out PDISPLAY_DEVICE lpDisplayDevice,
__in DWORD dwFlags
);
public: [DllImport("user32.dll", CharSet = CharSet::Auto,
BestFitMapping = true,CallingConvention = CallingConvention::Cdecl)]
static long ChangeDisplaySettingsEx( __in LPCTSTR lpszDeviceName,
__in DEVMODE *lpDevMode,
HWND hwnd,
__in DWORD dwflags,
__in LPVOID lParam
);
public: [DllImport("kernel32.dll", CharSet = CharSet::Auto,
BestFitMapping = true,CallingConvention = CallingConvention::Cdecl)]
static int GetCurrentThreadId();
//hook
public: [DllImport("user32.dll", CharSet = CharSet::Auto,
BestFitMapping = true,CallingConvention = CallingConvention::Cdecl)]
static IntPtr GetModuleHandle(LPCTSTR lpModuleName);
#if 0
public: [DllImport("user32.dll", CharSet = CharSet::Auto,
BestFitMapping = true,CallingConvention = CallingConvention::Cdecl)]
static IntPtr SetWindowsHookEx(int idHook,
HookProc^ lpfn,
IntPtr hMod,
unsigned int dwThreadId);
public: [DllImport("user32.dll", CharSet = CharSet::Auto,
BestFitMapping = true,CallingConvention = CallingConvention::Cdecl)]
static bool UnhookWindowsHookEx(IntPtr hhk);
public: [DllImport("user32.dll", CharSet = CharSet::Auto,
BestFitMapping = true,CallingConvention = CallingConvention::Cdecl)]
static int CallNextHookEx(IntPtr hhk, int nCode,
IntPtr wParam, IntPtr lParam);
#endif
private: int nScreenWidth;
private: int nScreenHeight;
private: Threading::Thread^ thrMemShared;
private: System::Void Form1_Load(System::Object^ sender, System::EventArgs^ e) {
nScreenWidth = GetSystemMetrics(SM_CXSCREEN);
nScreenHeight = GetSystemMetrics(SM_CYSCREEN);
bActiveMirror = false;
}
private: System::Void Form1_FormClosed(System::Object^ sender, System::Windows::Forms::FormClosedEventArgs^ e) {
}
private: System::Void Form1_FormClosing(System::Object^ sender, System::Windows::Forms::FormClosingEventArgs^ e) {
if(thrMemShared)
thrMemShared->Abort();
}
private: String^ strFileMemory;
private: HANDLE hFileMem;
private: HANDLE hMemShare;
private: LPVOID pBufMem;
private: void MirrorDriver(bool dwAttach)
{
DEVMODE devmode;
FillMemory(&devmode, sizeof(DEVMODE), 0);
devmode.dmSize = sizeof(DEVMODE);
devmode.dmDriverExtra = 0;
// Make sure we have a display on this thread.
BOOL change = EnumDisplaySettings(NULL,
ENUM_CURRENT_SETTINGS,
&devmode);
devmode.dmFields = DM_BITSPERPEL |
DM_PELSWIDTH |
DM_PELSHEIGHT |
DM_POSITION ;
if (change)
{
DISPLAY_DEVICE dispDevice;
FillMemory(&dispDevice, sizeof(DISPLAY_DEVICE), 0);
dispDevice.cb = sizeof(DISPLAY_DEVICE);
LPCWSTR deviceName = NULL;
devmode.dmDeviceName[0] = '\0';
INT devNum = 0;
BOOL result;
DWORD cxPrimary = 0xFFFFFFFF;
DWORD cyPrimary = 0xFFFFFFFF;
// First enumerate for Primary display device:
while (result = EnumDisplayDevices(NULL,
devNum,
&dispDevice,
0))
{
if (dispDevice.StateFlags & DISPLAY_DEVICE_PRIMARY_DEVICE)
{
// Primary device. Find out its dmPelsWidht and dmPelsHeight.
EnumDisplaySettings(dispDevice.DeviceName,
ENUM_CURRENT_SETTINGS,
&devmode);
cxPrimary = devmode.dmPelsWidth;
cyPrimary = devmode.dmPelsHeight;
break;
}
devNum++;
}
// error check
if (!result)
{
MessageBox::Show("No '%s' found.\n", "Microsoft Mirror Driver");
return;
}
if (cxPrimary == 0xffffffff || cyPrimary == 0xffffffff)
{
MessageBox::Show("cxPrimary or cyPrimary not valid\n");
return;
}
// Enumerate again for the mirror driver:
devNum = 0;
while (result = EnumDisplayDevices(NULL,
devNum,
&dispDevice,
0))
{
if (wcscmp(dispDevice.DeviceString,(wchar_t*)L"Microsoft Mirror Driver") == 0)
{
break;
}
devNum++;
}
// error check
if (!result)
{
MessageBox::Show("EnumDisplayDevices");
return;
}
CHAR deviceNum[MAX_PATH];
LPSTR deviceSub;
wcsupr(&dispDevice.DeviceKey[0]);
wchar_t* wcs1 = (wchar_t*)L"\\DEVICE";
deviceSub = (LPSTR)wcsstr(&dispDevice.DeviceKey[0],wcs1);
if (!deviceSub)
strcpy(&deviceNum[0], "DEVICE0");
else
strcpy(&deviceNum[0], ++deviceSub);
// Reset the devmode for mirror driver use:
FillMemory(&devmode, sizeof(DEVMODE), 0);
devmode.dmSize = sizeof(DEVMODE);
devmode.dmDriverExtra = 0;
devmode.dmFields = DM_BITSPERPEL |
DM_PELSWIDTH |
DM_PELSHEIGHT |
DM_POSITION;
wcscpy(&devmode.dmDeviceName[0], L"mirror");
deviceName = (LPCWSTR)&dispDevice.DeviceName[0];
// Attach and detach information is sent via the dmPelsWidth/Height
// of the devmode.
//
if (!dwAttach)
{
devmode.dmPelsWidth = 0;
devmode.dmPelsHeight = 0;
}
else
{
devmode.dmPelsWidth = cxPrimary;
devmode.dmPelsHeight = cyPrimary;
}
// Update the mirror device's registry data with the devmode. Dont
// do a mode change.
INT code =
ChangeDisplaySettingsEx((wchar_t*)deviceName,
&devmode,
NULL,
(CDS_UPDATEREGISTRY | CDS_NORESET),
NULL
);
// Now do the real mode change to take mirror driver changes into
// effect.
code = ChangeDisplaySettingsEx(NULL,
NULL,
NULL,
0,
NULL);
}
else
{
MessageBox::Show("Can't get display settings.\n");
}
}
private: System::Void InitMemoryFile() {
pBufMem = 0;
IntPtr ptr = System::Runtime::InteropServices::Marshal::StringToHGlobalUni(strFileMemory);
hFileMem = CreateFile((LPCWSTR)ptr.ToPointer(),
GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE
,NULL,OPEN_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL);
if(hFileMem)
hMemShare = CreateFileMapping(hFileMem,NULL,PAGE_READWRITE,0,0,NULL);
if(hMemShare)
pBufMem = MapViewOfFile(hMemShare,FILE_MAP_READ,0,0,0);
}
private: System::Void CloseMemoryFile()
{
if(pBufMem)
UnmapViewOfFile(pBufMem);
if(hMemShare)
CloseHandle(hMemShare);
if(hFileMem)
CloseHandle(hFileMem);
}
private: int count;
private: int time;
private: int jpegQuality;
private: System::Void btnSync_Click(System::Object^ sender, System::EventArgs^ e) {
Bitmap^ bmp = gcnew Bitmap(picDesktop->Width,picDesktop->Height,
System::Drawing::Imaging::PixelFormat::Format24bppRgb);
// Lock the bitmap's bits.
PUCHAR pBuf = (PUCHAR)pBufMem;
System::Drawing::Rectangle rect = System::Drawing::Rectangle(0,0,bmp->Width,bmp->Height);
System::Drawing::Imaging::BitmapData^ bmpData = bmp->LockBits( rect, System::Drawing::Imaging::ImageLockMode::ReadWrite, bmp->PixelFormat );
// Get the address of the first line.
IntPtr ptr = bmpData->Scan0;
// Declare an array to hold the bytes of the bitmap.
// This code is specific to a bitmap with 24 bits per pixels.
int bytes = bmpData->Stride * bmp->Height;
array<Byte>^rgbValues = gcnew array<Byte>(bytes);
bmp->UnlockBits(bmpData);
// Copy the RGB values into the array.
System::Runtime::InteropServices::Marshal::Copy( ptr, rgbValues, 0, bytes );
long end = 0;
long start = 0;
int xTrack = 0;
int yTrack = 0;
int line = 0;//line of the original image
int index = 0;
System::IO::MemoryStream^ str = gcnew System::IO::MemoryStream();
System::Drawing::Imaging::ImageCodecInfo^ encode = GetEncoderInfo("image/jpeg");
System::Drawing::Imaging::EncoderParameters^ para =
gcnew System::Drawing::Imaging::EncoderParameters(1);
unsigned char g = 45;
unsigned char b = 45;
unsigned char r = 45;
unsigned char a = 45;
count = 0;
try
{
count = Int32::Parse(txtFrame->Text);
}catch(Exception^ ex)
{
MessageBox::Show(ex->Message);
}
try
{
time = Int32::Parse(txtTime->Text);
}catch(Exception^ ex)
{
MessageBox::Show(ex->Message);
time = 10;
}
try
{
jpegQuality = Int32::Parse(txtJpegQuality->Text);
}catch(Exception^ ex)
{
MessageBox::Show(ex->Message);
jpegQuality = 10;
}
para->Param[0] = gcnew System::Drawing::Imaging::EncoderParameter(
System::Drawing::Imaging::Encoder::Quality, (__int64)jpegQuality);
start = GetTickCount();
while(count>0)
{
count--;
line = 0;
xTrack = 0;
yTrack = 0;
bmpData = bmp->LockBits( rect, System::Drawing::Imaging::ImageLockMode::ReadWrite, bmp->PixelFormat );
// Get the address of the first line.
ptr = bmpData->Scan0;
for ( int counter = 2; counter < rgbValues->Length; counter += 3 )
{
int ll = line*1280*4;
int ll1 = (line+1)*1280*4;
int ll2 = (line+2)*1280*4;
int xx = xTrack*2*4;
int lx = ll + xx;
int lx1 = ll1 + xx;
if(yTrack < 416)
{
g = ( *(pBuf+ lx) + *(pBuf+ lx + 4) + *(pBuf+ lx1) + *(pBuf+ lx1 + 4)) / 4;
b = ( *(pBuf+ lx+1) + *(pBuf+ lx + 5) + *(pBuf+ lx1+1) + *(pBuf+ lx1 + 5))/ 4;
r = ( *(pBuf+ lx+2) + *(pBuf+ lx + 6) + *(pBuf+ lx1+2) + *(pBuf+ lx1 + 6)) / 4;
}else
{
int lx2 = ll2 + xx;
g = ( *(pBuf+ lx) + *(pBuf+ lx + 4) + *(pBuf+ lx1) + *(pBuf+ lx1 + 4) + *(pBuf+ lx2) + *(pBuf+ lx2 + 4)) / 6;
b = ( *(pBuf+ lx+1) + *(pBuf+ lx + 5) + *(pBuf+ lx1+1) + *(pBuf+ lx1 + 5) + *(pBuf+ lx2+1) + *(pBuf+ lx2 + 5)) / 6;
r = ( *(pBuf+ lx+2) + *(pBuf+ lx + 6) + *(pBuf+ lx1+2) + *(pBuf+ lx1 + 6) + *(pBuf+ lx2+2) + *(pBuf+ lx2 + 6)) / 6;
}
xTrack++;
if(xTrack == 640)
{
xTrack = 0;
if(line< 832)
line+=2;
else
line+=3;
yTrack++;
if(yTrack == 480)
{
yTrack = 0;
}
}
rgbValues[ counter-2 ] = b;
rgbValues[ counter-1 ] = g;
rgbValues[ counter ] = r;
}
// Copy the RGB values back to the bitmap
System::Runtime::InteropServices::Marshal::Copy( rgbValues, 0, ptr, bytes );
// Unlock the bits.
bmp->UnlockBits( bmpData );
bmp->Save(str,encode,para);
Thread::Sleep(time);
}
end = GetTickCount();
lblTotalFrame->Text = (end-start).ToString() + " (ms)";
picDesktop->Image = bmp;
//for testing only
System::IO::FileStream^ f = System::IO::File::Open("c:\\test.jpeg",System::IO::FileMode::Create);
System::IO::BinaryWriter^ writer = gcnew System::IO::BinaryWriter(f);
writer->Write(str->ToArray());
f->Close();
bmp->Save("c:\\test.jpg",System::Drawing::Imaging::ImageFormat::Jpeg);
}
private: static System::Drawing::Imaging::ImageCodecInfo^ GetEncoderInfo(String^ MimeType) {
System::Drawing::Imaging::ImageCodecInfo^ Result = nullptr;
array<System::Drawing::Imaging::ImageCodecInfo^>^ Encoders = System::Drawing::Imaging::ImageCodecInfo::GetImageEncoders();
for (int i = 0; Result == nullptr && i < Encoders.Length; i++)
{
if (Encoders[i]->MimeType == MimeType)
{
Result = Encoders[i];
}
}
return Result;
}
private: bool bActiveMirror;
private: System::Void btnActiveMirror_Click(System::Object^ sender, System::EventArgs^ e) {
if(!bActiveMirror){
bActiveMirror = true;
MirrorDriver(bActiveMirror);
btnActiveMirror->Text = "&Deactive mirror";
InitMemoryFile();
btnSync->Enabled = true;
}else
{
bActiveMirror = false;
MirrorDriver(bActiveMirror);
btnActiveMirror->Text = "&Active mirror";
CloseMemoryFile();
btnSync->Enabled = false;
}
}
private: System::Void btnFI_Load_Click(System::Object^ sender, System::EventArgs^ e) {
}
};
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -