I am writing a screen capture application.
I used the code mentioned on this link for the application.
Following is my entire code for your reference:
// WangsNotesScrCapt2.cpp : Defines the entry point for the application.
//
#include "stdafx.h"
#include "WangsNotesScrCapt2.h"
//include d3d library
#include <d3d9.h>
#include <d3dx9tex.h>
#include <dinput.h>
//link d3d library
#pragma comment (lib, "d3d9.lib")
#pragma comment (lib, "D3dx9.lib")
#define MAX_LOADSTRING 100
#define WM_KEYDOWN 0x0100
// Global Variables:
HINSTANCE hInst; // current instance
TCHAR szTitle[MAX_LOADSTRING]; // The title bar text
TCHAR szWindowClass[MAX_LOADSTRING]; // the main window class name
//d3d objects
LPDIRECT3D9 d3d = NULL;
LPDIRECT3DDEVICE9 d3ddev = NULL;
// Forward declarations of functions included in this code module:
ATOM MyRegisterClass(HINSTANCE hInstance);
BOOL InitInstance(HINSTANCE, int);
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
INT_PTR CALLBACK About(HWND, UINT, WPARAM, LPARAM);
void releaseD3d();
void captureScreenD3d();
void initD3d(HWND hwnd);
int APIENTRY _tWinMain(_In_ HINSTANCE hInstance,
_In_opt_ HINSTANCE hPrevInstance,
_In_ LPTSTR lpCmdLine,
_In_ int nCmdShow)
{
UNREFERENCED_PARAMETER(hPrevInstance);
UNREFERENCED_PARAMETER(lpCmdLine);
// TODO: Place code here.
MSG msg;
HACCEL hAccelTable;
// Initialize global strings
LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
LoadString(hInstance, IDC_WANGSNOTESSCRCAPT2, szWindowClass, MAX_LOADSTRING);
MyRegisterClass(hInstance);
// Perform application initialization:
if (!InitInstance (hInstance, nCmdShow))
{
return FALSE;
}
hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_WANGSNOTESSCRCAPT2));
// Main message loop:
while (GetMessage(&msg, NULL, 0, 0))
{
if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
for (int k = 0; k < 10000; k++)
{
for (int j = 0; j < 10000; j++)
{
for (int i = 0; i < 100; i++)
{
}
}
}
//capture screen
captureScreenD3d();
//release d3d objects when this program is closed
releaseD3d();
return (int) msg.wParam;
}
#define BUFSIZE 65535
#define SHIFTED 0x8000
//
// FUNCTION: MyRegisterClass()
//
// PURPOSE: Registers the window class.
//
ATOM MyRegisterClass(HINSTANCE hInstance)
{
WNDCLASSEX wcex;
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.style = CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc = WndProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = hInstance;
wcex.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_WANGSNOTESSCRCAPT2));
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wcex.lpszMenuName = MAKEINTRESOURCE(IDC_WANGSNOTESSCRCAPT2);
wcex.lpszClassName = szWindowClass;
wcex.hIconSm = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));
return RegisterClassEx(&wcex);
}
//
// FUNCTION: InitInstance(HINSTANCE, int)
//
// PURPOSE: Saves instance handle and creates main window
//
// COMMENTS:
//
// In this function, we save the instance handle in a global variable and
// create and display the main program window.
//
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
HWND hWnd;
hInst = hInstance; // Store instance handle in our global variable
hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);
if (!hWnd)
{
return FALSE;
}
//init d3d objects
initD3d(hWnd);
ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);
return TRUE;
}
//
// FUNCTION: WndProc(HWND, UINT, WPARAM, LPARAM)
//
// PURPOSE: Processes messages for the main window.
//
// WM_COMMAND - process the application menu
// WM_PAINT - Paint the main window
// WM_DESTROY - post a quit message and return
//
//
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
int wmId, wmEvent;
PAINTSTRUCT ps;
HDC hdc;
switch (message)
{
case WM_COMMAND:
wmId = LOWORD(wParam);
wmEvent = HIWORD(wParam);
// Parse the menu selections:
switch (wmId)
{
case IDM_ABOUT:
DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);
break;
case IDM_EXIT:
DestroyWindow(hWnd);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
break;
case WM_PAINT:
hdc = BeginPaint(hWnd, &ps);
// TODO: Add any drawing code here...
EndPaint(hWnd, &ps);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
// Message handler for about box.
INT_PTR CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
UNREFERENCED_PARAMETER(lParam);
switch (message)
{
case WM_INITDIALOG:
return (INT_PTR)TRUE;
case WM_COMMAND:
if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
{
EndDialog(hDlg, LOWORD(wParam));
return (INT_PTR)TRUE;
}
break;
}
return (INT_PTR)FALSE;
}
void initD3d(HWND hwnd)
{
d3d = Direct3DCreate9(D3D_SDK_VERSION);
D3DPRESENT_PARAMETERS d3dpp;
ZeroMemory(&d3dpp, sizeof(d3dpp));
d3dpp.Windowed = TRUE;
d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
d3dpp.hDeviceWindow = hwnd;
d3d->CreateDevice(D3DADAPTER_DEFAULT,
D3DDEVTYPE_HAL,
hwnd,
D3DCREATE_SOFTWARE_VERTEXPROCESSING,
&d3dpp,
&d3ddev);
}
void captureScreenD3d()
{
UINT screenW = GetSystemMetrics(SM_CXSCREEN);
UINT screenH = GetSystemMetrics(SM_CYSCREEN);
LPDIRECT3DSURFACE9 pSurface;
d3ddev->CreateOffscreenPlainSurface(screenW, screenH, D3DFMT_A8R8G8B8, D3DPOOL_SCRATCH, &pSurface, NULL);
d3ddev->GetFrontBufferData(0, pSurface);
D3DXSaveSurfaceToFile(L"screen.bmp", D3DXIFF_BMP, pSurface, NULL, NULL);
pSurface->Release();
}
void releaseD3d()
{
d3ddev->Release();
d3d->Release();
}
It returns the actual screen for any normal window but if i run a game it returns a black image.
Is there any way I can also make it work with all the fullscreen games as well?
EDIT:
So I changed the way I call the capturescreen() function.
Now I call it in main like this as suggested by #pauld
d3ddev->BeginScene();
//capture screen
captureScreenD3d();
d3ddev->EndScene();
d3ddev->Present(NULL, NULL, NULL, NULL);
releaseD3d();
I am still getting a black image for fullscreen games and it works fine for every other application.
Related
I am trying to set up performance monitorint interrupt on counter overflow to collect some information. For this I created driver. I skip some part of code that are irrelevant.
driver.c
extern VOID EnableReadPmc();
extern VOID PmiHandle();
extern VOID GetIdt(IDT_INFO *idt);
extern ULONG64 GetCs();
#pragma pack(2)
typedef struct {
USHORT Limit;
ULONG64 Base;
}IDT_INFO;
#pragma pack()
typedef struct _entry {
ULONG64 Low;
ULONG64 High;
} entry;
PHYSICAL_ADDRESS lvt_perf_count_reg = {0xfee00340, 0x00000000};
PVOID map_lvt_perf_count_reg = NULL;
PHYSICAL_ADDRESS eoi_register = {0xfee000b0, 0x00000000};
PVOID map_eoi_register = NULL;
NTSTATUS IoCtlDispatch(IN PDEVICE_OBJECT pDeviceObject, IN PIRP pIrp) {
ULONG32 set_lvt_perf_count_reg = 0x000000ee;
//idt
IDT_INFO idtr;
entry *idt = NULL;
entry tmp_gate;
ULONG64 func;
ULONG64 seg;
ULONG64 int_setting;
//ovf status value
ULONG64 ovf_status;
pIrpStack = IoGetCurrentIrpStackLocation(pIrp);
switch (pIrpStack->Parameters.DeviceIoControl.IoControlCode) {
case IOCTL_INTERRUPT_SETTING_UP:
//disable pmc and clear ovf
WriteMsr(IA32_PERF_GLOBAL_CTRL, 0x00);
WriteMsr(IA32_FIXED_CTR_CTRL, 0x00);
ovf_status = ReadMsr(IA32_PERF_GLOBAL_STATUS);
WriteMsr(IA32_PERF_GLOBAL_OVF_CTRL, ovf_status);
//setting up lvt entry
map_lvt_perf_count_reg = MmMapIoSpace(lvt_perf_count_reg, 4, MmNonCached);
*(PULONG32)map_lvt_perf_count_reg = set_lvt_perf_count_reg;
map_eoi_register = MmMapIoSpace(eoi_register, 4, MmNonCached);
//setting up idt handler
idtr.Limit = 0;
idtr.Base = 0;
GetIdt(&idtr);
idt = idtr.Base;
tmp_gate.Low = 0;
tmp_gate.High = 0;
func = 0;
seg = 0;
int_setting = 0x8e00;
//p = 1 dpl = 0 type(interrupt gate) = 1110 ist = 0
seg = GetCs();
func = (ULONG64)PmiHandle;
tmp_gate.Low = func & 0x0ffff;
tmp_gate.Low = seg << 16 | tmp_gate.Low;
tmp_gate.Low = int_setting << 32 | tmp_gate.Low;
tmp_gate.Low = ((func & 0x0ffff0000) << 32) | tmp_gate.Low;
tmp_gate.High = (func & 0xffffffff00000000) >> 32;
idt[238] = tmp_gate;
MmUnmapIoSpace(map_lvt_perf_count_reg, 4);
map_lvt_perf_count_reg = NULL;
pIrp->IoStatus.Information = 0;
break;
default:
DbgPrint("Error in switch");
break;
}
status = pIrp->IoStatus.Status;
IoCompleteRequest(pIrp, IO_NO_INCREMENT);
return status;
}
pmihandle.asm
public PmiHandle
extern Handle : proc
.code
PmiHandle:
call Handle
add rsp, 8
iretq
end
handle.c
#define IA32_PERF_GLOBAL_CTRL 0x38f
#define IA32_PERF_GLOBAL_STATUS 0x38e
#define IA32_PERF_GLOBAL_OVF_CTRL 0x390
extern ULONG64 ovf_status_handle;
extern PVOID map_eoi_register;
VOID Handle() {
WriteMsr(IA32_PERF_GLOBAL_CTRL, 0x00);
ovf_status_handle = ReadMsr(IA32_PERF_GLOBAL_STATUS);
WriteMsr(IA32_PERF_GLOBAL_OVF_CTRL, ovf_status_handle);
DbgPrint("INTERRUPT_INTERRUPT_INTERRUPT");
if (map_eoi_register != NULL)
*(PULONG32)map_eoi_register = 0x0;
else
DbgPrint("EOI failed");
}
main.c application with which I turn on counters
#include <stdio.h>
#include "include/msr_sampling.h"
#define FILE_DEVICE_MSR 0x8000
#define IOCTL_INTERRUPT_SETTING_UP CTL_CODE(FILE_DEVICE_MSR, 0x805, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define IOCTL_FILE_TEST CTL_CODE(FILE_DEVICE_MSR, 0x806, METHOD_BUFFERED, FILE_ANY_ACCESS)
int main() {
SetProcForMsrCtr(); //set affinity mask for first proc
DriverOpen();
EnableReadPmc(); //enable __readpmc instruction
DWORD numberData = -1;
DeviceIoControl(hFile, IOCTL_INTERRUPT_SETTING_UP, NULL, 0, NULL, 0, &numberData, NULL);
ULONG64 value;
value = 0x000000000000000b;
WriteMsr(IA32_FIXED_CTR_CTRL, value);
value = 0xfffffffff000; //old value ffffffffc000
printf("%llu\n", __readpmc((1 << 30)));
WriteMsr(0x309, value);
printf("%llx\n", __readpmc((1 << 30)));
printf("=================================================\n");
ReadMsr(IA32_PERF_GLOBAL_CTRL, &value);
printf("%llX\n", value);
value = 0x0000000100000000;
WriteMsr(IA32_PERF_GLOBAL_CTRL, value);
printf("counter value: %llX\n", __readpmc((1 << 30)));
DriverClose();
system("pause");
return 0;
}
When I launch application my computer froze(does not respond to mouse movement and press key).
But if I generate interrupt with using assembly instuction INT it is OK.
I checked IDT and LVT entry via WinDbg they are correct.
What could be the problem?
Some informantion:
My processor is Intel Core i5-3210M. OS windows 7 x64. I do this on laptop.
I am a newbie working with Indy. This is my first time posting a question here.
My project has to send data to all clients at 60Hz. I am using TIdTCPServer for this, and to monitor keep-alives. My tool is very old, running on WinXP, using C++Builder 6 and Indy 8. There is a potential timeout issue, does anyone have a good thought how to handle it?
Here is my code:
Server Side
typedef struct
{
AnsiString PeerIP; //{ Cleint IP address }
AnsiString HostName; //{ Hostname }
int Id; // {Cleint ID}
} TClient;
// This is Multimedia timer callback function, on 60Hz
void CALLBACK mmTimerProc(UINT wTimerID, UINT msg, DWORD dwUser, DWORD dw1, DWORD dw2)
{
DWORD T1, T2;
TfmMain *pMain = (TfmMain *)dwUser;
int Index;
double dT;
TClient *pClient;
if (pMain->IsClosing) return;
if (pMain->Shutdown)
{
return;
}
pMain->UpdateServer1Data();
TList *pList = pMain->IdTCPServer1->Threads->LockList();
try
{
for(int X = 0; X < pList->Count; X++)
{
if (!pMain->IsClosing)
{
TIdPeerThread *AThread = (TIdPeerThread *)pList->Items[X];
if(AThread != NULL)
{
pClient = (TClient *)AThread->Data;
try
{
if(!AThread->Connection->ClosedGracefully)
{
// Send data to ALL Clients
AThread->Connection->WriteBuffer(&pMain->Data2Client, sizeof(pMain->Data2Client), true);
}
}
catch(Exception &E)
{
if(!AThread->Stopped)
{
AThread->Stop();
AThread->Connection->Disconnect();
}
}
}
}
}
}
__finally
{
pMain->IdTCPServer1->Threads->UnlockList();
}
// Shutdown computer or close application
if(pMain->SimIos.Status.iSimStatus == 11)
{
pMain->Shutdown = true;
pMain->CloseApp();
}
}
void __fastcall TfmMain::IdTCPServer1Connect(TIdPeerThread *AThread)
{
TClient *pClient = NULL;
AnsiString ABuffer, text;
AnsiString PeerIP = AThread->Connection->Binding->PeerIP;
TDateTime TimeConnected = Now();
ABuffer = AThread->Connection->ReadLn();
if((ABuffer.Pos("TT") == 0) && (ABuffer.Pos("IG") == 0) && (ABuffer.Pos("RR") == 0))
{
text = AnsiString().sprintf("1>>> Unknown(%s) on %s connected illegal!...",
PeerIP, DateTimeToStr(TimeConnected));
WriteMsg(text);
AThread->Connection->Disconnect();
return;
}
if(ABuffer.Pos("IG") != 0)
{
pClient = new TClient;
pClient->PeerIP = PeerIP;
pClient->HostName = Clients[eIG];
pClient->Id = eIG;
AThread->Data = (TObject *)pClient;
AThread->FreeOnTerminate = true;
// Report client is on line
}
text = AnsiString().sprintf("1>>>%s(%s) on %s on line!...",
pClient->HostName, PeerIP, DateTimeToStr(TimeConnected));
WriteMsg(text);
}
//---------------------------------------------------------------------------
void __fastcall TfmMain::IdTCPServer1Disconnect(TIdPeerThread *AThread)
{
TClient *pClient = NULL;
AnsiString Msg;
if (IsClosing) return;
pClient = (TClient *)AThread->Data;
if(pClient->Id == 1)
{
// Report client is off line
Msg = AnsiString().sprintf("1>>>%s(%s) on %s off line...",
pClient->HostName, pClient->PeerIP, DateTimeToStr(Now()));
WriteMsg(Msg);
}
delete pClient;
AThread->Data = NULL;
AThread->Terminate();
try
{
IdTCPServer1->Threads->LockList()->Remove(AThread);
}
__finally
{
IdTCPServer1->Threads->UnlockList();
}
}
//---------------------------------------------------------------------------
void __fastcall TfmMain::IdTCPServer1Execute(TIdPeerThread *AThread)
{
TClient *pClient;
if (!AThread->Terminated && !IsClosing)
{
pClient = (TClient *)AThread->Data;
if((pClient != NULL) && (pClient->Id != 0))
{
try
{
if(pClient->Id == 1)
{
// Report client still alive
}
}
catch(Exception &E)
{
if (!IsClosing)
{
if(!AThread->Stopped)
{
AThread->Stop();
AThread->Connection->Disconnect();
}
}
}
}
}
}
Client side
void __fastcall TSocketThread::Execute()
{
unsigned long ulCheckSum;
SIM_SVR1_ACK_STRUCT Ack2Svr;
SIM_SVR_DATA DataFromSvr;
int Counter;
memset(&DataFromSvr, 0, sizeof(DataFromSvr));
memset(&Ack2Svr, 0, sizeof(Ack2Svr));
Counter = 0;
// fetch and process commands until the connection or thread is terminated
while (!this->Terminated && FSocket->Connected())
{
try
{
// recieve data from server
FSocket->ReadBuffer(&DataFromSvr, sizeof(DataFromSvr));
// check CRC
ulCheckSum = CRC_32((unsigned char*)&DataFromSvr.SimData, sizeof(DataFromSvr.SimData));
if (ulCheckSum == DataFromSvr.uiCheckSum)
{
FSmIpcUtil->Writeto(&DataFromSvr.SimData, DATA_OFFSET, sizeof(DataFromSvr.SimData));
}
else
{
// counter to record error
Synchronize(UpdateCaption);
}
// read return from local SM
FSmIpcUtil->Readfrom(&Ack2Svr, ACK_OFFSET, sizeof(Ack2Svr));
FSocket->WriteBuffer(&Ack2Svr, sizeof(Ack2Svr));
if (DataFromSvr.SimData.SimIgTgt.Acdata.iSimStatus == 11)
{
Terminate();
FSocket->Disconnect();
PostMessage(Application->Handle, WM_SHUTDOWN, 0, 0);
Sleep(500);
}
}
catch (EIdException& E)
{
this->Terminate();
FSocket->Disconnect();
}
}
}
There are several issues with your code.
A multimedia timer callback is very restricted in what it is allowed to do:
Applications should not call any system-defined functions from inside a callback function, except for PostMessage, timeGetSystemTime, timeGetTime, timeSetEvent, timeKillEvent, midiOutShortMsg, midiOutLongMsg, and OutputDebugString.
If transmission speed is important, don't have the timer callback do the broadcasting at all. Save the data somewhere safe, and then have each TIdTCPServer thread grab the latest data on its own time. This also keeps each connection thread isolated so one connection cannot affect any other connection if problems occur.
DO NOT set the TIdPeerThread::FreeOnTerminate to true, DO NOT call TIdPeerThread::Stop(), DO NOT manually remove threads from the TIdTCPServer::Threads property. You do not own the threads, TIdTCPServer does, and it will manage them for you. If you want to stop a given thread, closing the thread's socket is all you need to do. But by moving all of the sending logic into OnExecute where it belongs, you can let TIdTCPServer handle any errors and close the socket for you.
Your OnConnect event handler is setting AThread->Data only if an IG client connects, but your OnConnect and OnDisconnect handlers are not checking for that condition before attempting to access the TClient object.
Your OnDisconnect event handler is leaking memory if IsClosing is true. And it is calling Threads->UnlockList() without calling Threads->LockList() first. Attempting to unlock the list when it is not locked by the calling thread will cause errors and deadlocks.
Try something more like this:
struct TClient
{
AnsiString PeerIP; //{ Client IP address }
AnsiString HostName; //{ Hostname }
int Id; //{ Client ID }
};
void CALLBACK mmTimerProc(UINT wTimerID, UINT msg, DWORD dwUser, DWORD dw1, DWORD dw2)
{
TfmMain *pMain = (TfmMain *)dwUser;
if (pMain->IsClosing || pMain->Shutdown) return;
pMain->UpdateServer1Data();
// make sure pMain->Data2Client is thread-safe...
// set a signal that Data2Client has been updated...
// Shutdown computer or close application
if (pMain->SimIos.Status.iSimStatus == 11)
{
pMain->Shutdown = true;
pMain->CloseApp();
}
}
void __fastcall TfmMain::IdTCPServer1Connect(TIdPeerThread *AThread)
{
TClient *pClient;
AnsiString ABuffer, text;
AnsiString PeerIP = AThread->Connection->Binding->PeerIP;
TDateTime TimeConnected = Now();
ABuffer = AThread->Connection->ReadLn();
if ((ABuffer.Pos("TT") == 0) && (ABuffer.Pos("IG") == 0) && (ABuffer.Pos("RR") == 0))
{
text = AnsiString().sprintf("1>>> Unknown(%s) on %s connected illegal!...", PeerIP.c_str(), DateTimeToStr(TimeConnected).c_str());
WriteMsg(text);
AThread->Connection->Disconnect();
return;
}
pClient = new TClient;
pClient->PeerIP = PeerIP;
if (ABuffer.Pos("IG") != 0)
{
pClient->HostName = Clients[eIG];
pClient->Id = eIG;
}
else
pClient->Id = 0;
AThread->Data = (TObject *)pClient;
// Report client is on line
text = AnsiString().sprintf("1>>>%s(%s) on %s on line!...", pClient->HostName.c_str(), PeerIP.c_str(), DateTimeToStr(TimeConnected).c_str());
WriteMsg(text);
}
void __fastcall TfmMain::IdTCPServer1Disconnect(TIdPeerThread *AThread)
{
TClient *pClient = (TClient *)AThread->Data;
AnsiString Msg;
AThread->Data = NULL;
if (pClient)
{
// Report client is off line
Msg = AnsiString().sprintf("1>>>%s(%s) on %s off line...",
pClient->HostName.c_str(), pClient->PeerIP.c_str(), DateTimeToStr(Now()).c_str());
WriteMsg(Msg);
delete pClient;
}
}
void __fastcall TfmMain::IdTCPServer1Execute(TIdPeerThread *AThread)
{
TClient *pClient;
if (IsClosing) return;
// make sure pMain->Data2Client is thread-safe...
if (Data2Client has been updated since last event)
{
AThread->Connection->WriteBuffer(&pMain->Data2Client, sizeof(pMain->Data2Client), true);
}
pClient = (TClient *)AThread->Data;
// Report client still alive
}
My problem with this code is that when I run it in visual C++ A window pops up
but then it just crashes. It is not responding and I cannot click exit. I have to pull up the
task manager to get rid of the window. I am new to windows programming and direct X.
Below I will post were I think the problem is.
#include <d3d9.h>
#include <time.h>
#define APPTITLE "Direct3D_Windowed"
LRESULT WINAPI WinProc(HWND, UINT, WPARAM, LPARAM);
ATOM MyRegisterClass(HINSTANCE);
int Game_Init(HWND);
void GAME_RUN(HWND);
void GAME_END(HWND);
LPDIRECT3D9 d3d = NULL;
LPDIRECT3DDEVICE9 d3ddev = NULL;
// Over here, after GAME_END() is called, I tried separating the POSTQUITMESSAGE But I
I just got an error.
LRESULT WINAPI WinProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch(msg )
{
case WM_DESTROY:
GAME_END(hWnd);
PostQuitMessage(0);
return 0;
}
return DefWindowProc(hWnd, msg, wParam, lParam);
}
ATOM MyRegisterClass(HINSTANCE hInstance)
{
WNDCLASSEX wc;
wc.cbSize = sizeof(WNDCLASSEX);
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = (WNDPROC)WinProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
wc.hIcon = NULL;
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
wc.lpszMenuName = NULL;
wc.lpszClassName = APPTITLE;
wc.hIconSm = NULL;
return RegisterClassEx(&wc);
}
// I got this code from a book that I am reading and realized that WinProc is not being
called in this function. Is this the potential problem? Were would I put the WinProc
function call if it is supposed to be here in WinMain
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
MSG msg = {0};
MyRegisterClass(hInstance);
HWND hWnd;
hWnd = CreateWindow(
APPTITLE,
APPTITLE,
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
CW_USEDEFAULT,
500,
400,
NULL,
NULL,
hInstance,
NULL);
if(!hWnd)
return FALSE;
ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);
if(!Game_Init(hWnd))
return 0;
int done = 0;
while(!done)
{
if(msg.message == WM_QUIT)
{
if(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
MessageBox(hWnd, "Recieve WM_QUIT message", "WinMain", MB_OK);
done = 1;
}
TranslateMessage(&msg);
DispatchMessage(&msg);
}
else
GAME_RUN(hWnd);
}
return msg.wParam;
}
int Game_Init(HWND hWnd)
{
MessageBox(hWnd, "Program is about to start", "Game_Init", MB_OK);
d3d = Direct3DCreate9(D3D_SDK_VERSION);
if(d3d == NULL)
{
MessageBox(hWnd, "Error initializing Direct3D", "Error", MB_OK);
return 0;
}
D3DPRESENT_PARAMETERS d3dpp;
ZeroMemory(&d3dpp, sizeof(d3dpp));
d3dpp.Windowed = TRUE;
d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
d3dpp.BackBufferFormat = D3DFMT_UNKNOWN;
d3d->CreateDevice(
D3DADAPTER_DEFAULT,
D3DDEVTYPE_HAL,
hWnd,
D3DCREATE_SOFTWARE_VERTEXPROCESSING,
&d3dpp,
&d3ddev);
if(d3ddev == NULL)
{
MessageBox(hWnd, "Error creating Direct device", "Error", MB_OK);
return 0;
}
srand(time(NULL));
return 1;
}
void GAME_RUN(HWND hWnd)
{
if(d3ddev == NULL)
return;
d3ddev->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0, 255, 255), 1.0f, 0);
if(d3ddev->BeginScene())
{
d3ddev->EndScene();
}
d3ddev->Present(NULL, NULL, NULL, NULL);
}
void GAME_END(HWND hWnd)
{
MessageBox(hWnd, "Program is about to end", "Game End", MB_OK);
if(d3ddev != NULL)
d3ddev->Release();
if(d3d != NULL)
d3d->Release();
}
Have a look at this?
if(msg.message == WM_QUIT)
In your while-loop.
Perhaps change that to, say:
if(true)
Reason: you want your application to pass on all messages, not just the ones that cause it to quit. Say for instance when windows wants your application to draw itself. Basically, your current code doenst allow your application to do anything except quitting.
If you want to do something special when the application quits, add another case WM_QUIT: after the already existing case WM_DESTROY: in WinProc().
The current location for GAME_RUN(hWnd); will not work out for you.
You want to either put that in a seperate thread (easiest, and highest performance). Or you want to use some timers, and handle it with case WM_TIMER: after your case WM_DESTROY:. Or alternatively make up your own user defined message.
I need to get Device Context (DC ) from directx3d. Here some code snap.
1.CREATE DEVICE:
int windowWidth = 640;
int windowHeight = 480;
IDirect3D9* direct3D9 = Direct3DCreate9(D3D_SDK_VERSION);
if(direct3D9 == NULL)
{
return FALSE;
}
D3DDISPLAYMODE *d3ddisplayMode =(D3DDISPLAYMODE *)calloc(1,sizeof(D3DDISPLAYMODE));
hr = direct3D9->GetAdapterDisplayMode(D3DADAPTER_DEFAULT,d3ddisplayMode);
if(hr != D3D_OK)
{
free(d3ddisplayMode);
direct3D9->Release();
return FALSE;
}
D3DPRESENT_PARAMETERS *d3dpresentParam =(D3DPRESENT_PARAMETERS*)calloc(1,sizeof(D3DPRESENT_PARAMETERS));
d3dpresentParam->Windowed = TRUE;
d3dpresentParam->hDeviceWindow = NULL;
d3dpresentParam->SwapEffect = D3DSWAPEFFECT_DISCARD;
d3dpresentParam->BackBufferFormat = d3ddisplayMode->Format;
d3dpresentParam->BackBufferWidth = windowWidth;
d3dpresentParam->BackBufferHeight = windowHeight;
d3dpresentParam->BackBufferCount = 1;
free(d3ddisplayMode);
hr = direct3D9->CreateDevice(D3DADAPTER_DEFAULT,D3DDEVTYPE_HAL,NULL,D3DCREATE_SOFTWARE_VERTEXPROCESSING,d3dpresentParam,&direct3D9Device);
2.CRETAE TEXTURE:
hr = D3DXCreateTexture(direct3D9Device,bmpWidth,bmpHeight,1,0,D3DFMT_X8R8G8B8,D3DPOOL_MANAGED,&pTexture);
3.DISPLAY IMAGE:
float left = 0,top =0,width =640,height=480;
direct3D9Device->BeginScene();
D3DXMATRIX mat;
D3DXVECTOR3 pos;
pos.x = (bmpWidth * left) / width;
pos.y = (bmpHeight * top) / height;
pos.z = 0;
d3dxSprite->Begin(D3DXSPRITE_ALPHABLEND);
D3DXVECTOR2 scaling((width/bmpWidth),(height/bmpHeight));
if(pTexture == direct3DTextureRemote )
{
D3DXVECTOR2 spriteCentre((width/2),(height/2));
D3DXMatrixTransformation2D(&mat,NULL,0.0,&scaling,&spriteCentre,NULL,NULL);
}
else
{
D3DXMatrixTransformation2D(&mat,NULL,0.0,&scaling,NULL,NULL,NULL);
}
d3dxSprite->SetTransform(&mat);
d3dxSprite->Draw(pTexture,NULL,NULL,&pos,0xFFFFFFFF);
d3dxSprite->End();
direct3D9Device->EndScene();
direct3D9Device->Present( NULL, NULL, NULL, NULL );
Now Working probely. I can get dc from window like HDC hdc = ::GetDC(hwnd) but in my case if there is no window(i.e. windowless) then how can i get DC from directx. please give some piece of code get DC from directx device.
Call GetDC with null as argument:
HDC hdc = ::GetDC(0);
Quote from MSDN:
Parameters
hWnd [in]
A handle to the window whose DC is to be retrieved.
If this value is NULL, GetDC retrieves the DC for the entire screen.
Edit:
As we know now that you are using NPAPI, here is a possible solution:
Call NPAPI function NPN_GetValue() with NPNVnetscapeWindow parameter. Returned HWND is a handle to plug-in drawing surface. Use it when create DirectX device and to retrieve HDC.
Alternatively, you could try to retrieve the back buffer (IDirect3DSurface9) via IDirect3DDevice9::GetRenderTarget() method and then retrieve its HDC via IDirect3DSurface9::GetDC() method.
#include "ntddk.h"
NTSTATUS DriverEntry( IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath );
VOID DriverUnload( IN PDRIVER_OBJECT DriverObject );
INT InitializeGlobalAddressSpace(VOID);
#define BUF_SIZE 256
TCHAR szName[]=TEXT("\\BaseNamedObjects\\MyFileMappingObject");
char szMsg[]="New Message";
NTSTATUS DriverEntry( IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath )
{
NTSTATUS ntStatus = STATUS_UNSUCCESSFUL;
DriverObject->DriverUnload = DriverUnload;
DbgPrint("Hello World Driver Loaded!");
InitializeGlobalAddressSpace();
ntStatus = STATUS_SUCCESS;
return ntStatus;
}
VOID DriverUnload( IN PDRIVER_OBJECT DriverObject )
{
DbgPrint("Hello World Driver unloaded!");
}
INT InitializeGlobalAddressSpace(VOID)
{
OBJECT_ATTRIBUTES ObjectAttributes;
UNICODE_STRING PhysMemName = RTL_CONSTANT_STRING(L"\\BaseNamedObjects\\MyFileMappingObject");
NTSTATUS Status;
HANDLE PhysMemHandle;
PVOID BaseAddress;
PVOID NullAddress;
LARGE_INTEGER Offset;
ULONG ViewSize;
BaseAddress = NULL;
Offset.LowPart = 0;
Offset.HighPart = 0;
ViewSize = 0;
InitializeObjectAttributes(&ObjectAttributes,&PhysMemName,0,NULL,NULL);
Status = ZwOpenSection(&PhysMemHandle, SECTION_ALL_ACCESS, &ObjectAttributes);
if (!NT_SUCCESS(Status))
{
DbgPrint("Couldn't open Global\\MyFileMappingObject - error:%x\n",Status);
return(0);
}
Status = ZwMapViewOfSection(PhysMemHandle,ZwCurrentProcess(),&BaseAddress,0,0,&Offset,&ViewSize,ViewShare,0,PAGE_READWRITE);
if (!NT_SUCCESS(Status))
{
DbgPrint("Couldn't open Global\\MyFileMappingObject - error:%x\n",Status);
return(0);
}
DbgPrint("%s",Status);
try
{
memcpy((PVOID)Status, szMsg, (strlen(szMsg) * sizeof(TCHAR)));
}
except(EXCEPTION_EXECUTE_HANDLER)//will crash without this.
{
DbgPrint("error:%x");
}
return (1);
}
memcpy function causes the driver to crash the system, am i doing something wrong within the zwopensection/zwmapviewofsection to cause this to happen. Note: driver does not crash system with try/except function around it.
You are trying to write something in Status:
memcpy((PVOID)Status, szMsg, (strlen(szMsg) * sizeof(TCHAR)));
Actually you are supposed to write in BaseAddress ... :-)