I'm trying to use MSDN's Direct2D basic tutorial, but the window won't show up, it output's the normal debug info, but no window. I've tried playing about with the WinMain() parameters and the ShowWindow() function, but it still refuses to work. Allso in the debug info there's this, but i don't think it's relevant. \NVIDIA Corporation\coprocmanager\nvdxgiwrap.dll'. Cannot find or open the PDB file.
Here's the code.
#include "RenderHeader.h"
//Main window function.
int WINAPI WinMain(
HINSTANCE /* hInstance */,
HINSTANCE /* hPrevInstance */,
LPSTR /* lpCmdLine */,
int /* nCmdShow */)
{
// Use HeapSetInformation to specify that the process should
// terminate if the heap manager detects an error in any heap used
// by the process.
// The return value is ignored, because we want to continue running in the
// unlikely event that HeapSetInformation fails.
HeapSetInformation(NULL, HeapEnableTerminationOnCorruption, NULL, 0);
if (SUCCEEDED(CoInitialize(NULL)))
{
{
GameRender app;
if (SUCCEEDED(app.Initialize()))
{
//Runs the application message loop.
app.RunMessageLoop();
}
}
CoUninitialize();
}
return 0;
}
GameRender::GameRender() :
m_hwnd(NULL),
m_pDirect2DFactory(NULL),
m_pRenderTarget(NULL),
m_pLightSlateGrayBrush(NULL),
m_pCornflowerBlueBrush(NULL)
{
}
GameRender::~GameRender()
{
SafeRelease(&m_pDirect2DFactory);
SafeRelease(&m_pRenderTarget);
SafeRelease(&m_pLightSlateGrayBrush);
SafeRelease(&m_pCornflowerBlueBrush);
}
HRESULT GameRender::Initialize()
{
HRESULT hRes;
/* Initialize device-indpendent resources, such
as the Direct2D factory.*/
hRes = CreateDeviceIndependantResources();
if (SUCCEEDED(hRes))
{
WNDCLASSEX Window = { sizeof(WNDCLASSEX) } ;
Window.style = CS_HREDRAW | CS_VREDRAW;
Window.lpfnWndProc = GameRender::WndProc;
Window.cbClsExtra = 0;
Window.cbWndExtra = sizeof(LONG_PTR);
Window.hInstance = HINST_THISCOMPONENT;
Window.hbrBackground = NULL;
Window.lpszMenuName = NULL;
Window.hCursor = LoadCursor(NULL, IDI_APPLICATION);
Window.lpszClassName = L"D2DDemoApp";
RegisterClassEx(&Window);
/* Because the CreateWindow function takes its size in pixels,
obtain the system DPI and use it to scale the window size.*/
FLOAT DpiX, DpiY;
/* The factory returns the current system DPI. This is also the value it will use
to create its own windows.*/
m_pDirect2DFactory->GetDesktopDpi(&DpiX, &DpiY);
//Create Window
m_hwnd = CreateWindow(L"D2PDemoApp",
L"Direct 2D Demo App",
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
CW_USEDEFAULT,
static_cast<UINT>(ceil(640.f * DpiX / 96.f)),
static_cast<UINT>(ceil(480.f * DpiY / 96.f)),
NULL,
NULL,
HINST_THISCOMPONENT,
this);
hRes = m_hwnd ? S_OK : E_FAIL;
if (SUCCEEDED(hRes))
{
ShowWindow(m_hwnd, SW_SHOWNORMAL);
UpdateWindow(m_hwnd);
}
}
return hRes;
}
HRESULT GameRender::CreateDeviceIndependantResources()
{
HRESULT hr = S_OK;
//Create a direct2D Factory
hr = D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, &m_pDirect2DFactory);
return hr;
}
HRESULT GameRender::CreateDeviceDependantResources()
{
HRESULT hr = S_OK;
if(!&m_pRenderTarget)
{
RECT rc;
GetClientRect(m_hwnd, &rc);
D2D1_SIZE_U size = D2D1::SizeU(rc.right - rc.left, rc.bottom - rc.top);
//Create a render target.
hr = m_pDirect2DFactory->CreateHwndRenderTarget(D2D1::RenderTargetProperties(), D2D1::HwndRenderTargetProperties(m_hwnd, size), &m_pRenderTarget);
if (SUCCEEDED(hr))
{
// Create a gray brush.
hr = m_pRenderTarget->CreateSolidColorBrush(
D2D1::ColorF(D2D1::ColorF::LightSlateGray),
&m_pLightSlateGrayBrush);
}
if (SUCCEEDED(hr))
{
// Create a blue brush.
hr = m_pRenderTarget->CreateSolidColorBrush(
D2D1::ColorF(D2D1::ColorF::CornflowerBlue),
&m_pCornflowerBlueBrush
);
}
}
return hr;
}
void GameRender::DiscardDeviceResources()
{
SafeRelease(&m_pRenderTarget);
SafeRelease(&m_pLightSlateGrayBrush);
SafeRelease(&m_pCornflowerBlueBrush);
}
void GameRender::RunMessageLoop()
{
MSG Message;
while (GetMessage(&Message, NULL, 0, 0))
{
TranslateMessage(&Message);
DispatchMessage(&Message);
}
}
HRESULT GameRender::OnDraw()
{
HRESULT hr = S_OK;
hr = CreateDeviceDependantResources();
if (SUCCEEDED(hr))
{
m_pRenderTarget->BeginDraw();
m_pRenderTarget->SetTransform(D2D1::Matrix3x2F::Identity());
m_pRenderTarget->Clear(D2D1::ColorF(D2D1::ColorF::White));
D2D1_SIZE_F rtSize = m_pRenderTarget->GetSize();
// Draw a grid background.
int width = static_cast<int>(rtSize.width);
int height = static_cast<int>(rtSize.height);
for (int x = 0; x < width; x += 10)
{
m_pRenderTarget->DrawLine(
D2D1::Point2F(static_cast<FLOAT>(x), 0.0f),
D2D1::Point2F(static_cast<FLOAT>(x), rtSize.height),
m_pLightSlateGrayBrush,
0.5f
);
}
for (int y = 0; y < height; y += 10)
{
m_pRenderTarget->DrawLine(
D2D1::Point2F(0.0f, static_cast<FLOAT>(y)),
D2D1::Point2F(rtSize.width, static_cast<FLOAT>(y)),
m_pLightSlateGrayBrush,
0.5f
);
}
// Draw two rectangles.
D2D1_RECT_F rectangle1 = D2D1::RectF(
rtSize.width/2 - 50.0f,
rtSize.height/2 - 50.0f,
rtSize.width/2 + 50.0f,
rtSize.height/2 + 50.0f
);
D2D1_RECT_F rectangle2 = D2D1::RectF(
rtSize.width/2 - 100.0f,
rtSize.height/2 - 100.0f,
rtSize.width/2 + 100.0f,
rtSize.height/2 + 100.0f
);
// Draw a filled rectangle.
m_pRenderTarget->FillRectangle(&rectangle1, m_pLightSlateGrayBrush);
// Draw the outline of a rectangle.
m_pRenderTarget->DrawRectangle(&rectangle2, m_pCornflowerBlueBrush);
hr = m_pRenderTarget->EndDraw();
}
if (hr == D2DERR_RECREATE_TARGET)
{
hr = S_OK;
DiscardDeviceResources();
}
return hr;
}
void GameRender::OnResize(UINT width, UINT height)
{
if (m_pRenderTarget)
{
// Note: This method can fail, but it's okay to ignore the
// error here, because the error will be returned again
// the next time EndDraw is called.
m_pRenderTarget->Resize(D2D1::SizeU(width,
height));
}
}
LRESULT CALLBACK GameRender::WndProc(
HWND hwnd,
UINT message,
WPARAM wParam,
LPARAM lParam)
{
LRESULT result = 0;
if (message == WM_CREATE)
{
LPCREATESTRUCT pcs = (LPCREATESTRUCT)lParam;
GameRender *pGameRender = (GameRender *)pcs->lpCreateParams;
::SetWindowLongPtrW(
hwnd,
GWLP_USERDATA,
PtrToUlong(pGameRender)
);
result = 1;
}
else
{
GameRender *pGameRender = reinterpret_cast<GameRender *>(static_cast<LONG_PTR>(
::GetWindowLongPtrW(
hwnd,
GWLP_USERDATA
)));
bool wasHandled = false;
if (pGameRender)
{
switch (message)
{
case WM_SIZE:
{
UINT width = LOWORD(lParam);
UINT height = HIWORD(lParam);
pGameRender->OnResize(width, height);
}
result = 0;
wasHandled = true;
break;
case WM_DISPLAYCHANGE:
{
InvalidateRect(hwnd, NULL, FALSE);
}
result = 0;
wasHandled = true;
break;
case WM_PAINT:
{
pGameRender->OnDraw();
ValidateRect(hwnd, NULL);
}
result = 0;
wasHandled = true;
break;
case WM_DESTROY:
{
PostQuitMessage(0);
}
result = 1;
wasHandled = true;
break;
}
}
if (!wasHandled)
{
result = DefWindowProc(hwnd, message, wParam, lParam);
}
}
return result;
}
Assuming that "RenderHeader.h" exists in your project's directory and it includes the windows header, then your problem is that you're not passing WinMain the variables it needs to function. 'HINSTANCE', 'LPSTR' and 'int' are all variable types, but you need to give them a name, otherwise they don't exist and the function won't work.
So this would be right
int WINAPI WinMain( HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int uCmdShow )
{
// The rest of the code
}
The names of the variables are commented out on the code in your question :P
Related
I was making a program that draws two lines and a circle in the window, for this I used Direct2D.
I was doing a program that draws two lines and a circle in the window. I noticed a problem and that is that when drawing a line of coordinates (100,200), (200,200), that line is not drawn in the pixels (100,200) and ( 200,200). I checked this by reading the coordinates of the mouse in the window and seeing if the line actually has the coordinates that I mentioned.
Do a little more research, and according to Microsoft, direct2d works with dpi and not physical pixels.
So is there a way to work directly with pixels like in Processing or Win32 where the position of the controls is expressed in physical pixels of the window.
#include <d2d1_3.h>
#include <d2d1_3helper.h>
#include <d3d11_1.h>
#include <dxgi1_6.h>
#include <string>
#pragma comment(lib,"d3d11")
#pragma comment(lib,"d2d1")
#pragma comment(lib,"dxgi")
#pragma warning(disable : 4996)
using namespace D2D1;
using namespace std;
template<typename Interface> void SafeRelease(Interface**);
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
int APIENTRY wWinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInst
, _In_ LPWSTR lpCmdLine, _In_ int nCmdShow) {
UNREFERENCED_PARAMETER(hPrevInst);
UNREFERENCED_PARAMETER(lpCmdLine);
WNDCLASS wc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hbrBackground = NULL;
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_WINLOGO));
wc.hInstance = hInstance;
wc.lpfnWndProc = WndProc;
wc.lpszClassName = L"Demo_Wnd_Class";
wc.lpszMenuName = NULL;
wc.style = 0;
RegisterClass(&wc);
DWORD dwTopLevelWndStyle = WS_OVERLAPPEDWINDOW ^ (WS_THICKFRAME | WS_MAXIMIZEBOX);
RECT clientRc = { 0,0,640,480 };
AdjustWindowRect(&clientRc, dwTopLevelWndStyle, FALSE);
HWND hWnd = CreateWindow(L"Demo_Wnd_Class", L"Direct2DDemo", dwTopLevelWndStyle, CW_USEDEFAULT, CW_USEDEFAULT
, clientRc.right - clientRc.left, clientRc.bottom - clientRc.top, NULL, NULL, hInstance, NULL);
ShowWindow(hWnd, SW_SHOWDEFAULT);
MSG msg;
ZeroMemory(&msg, sizeof(MSG));
ID3D11Device* d3dDevice;
IDXGIDevice* dxgiDevice = NULL;
D3D_FEATURE_LEVEL featureLevels[] = {
D3D_FEATURE_LEVEL_11_1,
D3D_FEATURE_LEVEL_11_0,
D3D_FEATURE_LEVEL_10_1,
D3D_FEATURE_LEVEL_10_0,
D3D_FEATURE_LEVEL_9_3,
D3D_FEATURE_LEVEL_9_2,
D3D_FEATURE_LEVEL_9_1,
};
HRESULT hr = D3D11CreateDevice(NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, D3D11_CREATE_DEVICE_BGRA_SUPPORT, featureLevels
, 7, D3D11_SDK_VERSION, &d3dDevice, NULL, NULL);
if (SUCCEEDED(hr)) {
OutputDebugString(L"D3D11 Device created successful\n");
hr = d3dDevice->QueryInterface(__uuidof(IDXGIDevice), (void**)&dxgiDevice);
}
ID2D1Device6* d2dDevice = NULL;
ID2D1DeviceContext6* d2dDeviceContext = NULL;
IDXGIFactory2* dxgiFactory = NULL;
IDXGISwapChain1* dxgiSwapChain = NULL;
IDXGISurface *dxgiBackBufferSurface = NULL; // Back buffer
ID2D1Bitmap1* bmpTarget = NULL;
ID2D1SolidColorBrush* shapeBr = NULL;
DXGI_SWAP_CHAIN_DESC1 dscd;
dscd.AlphaMode = DXGI_ALPHA_MODE_IGNORE;
dscd.BufferCount = 2;
dscd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
dscd.Flags = 0;
dscd.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
dscd.Height = 480;
dscd.SampleDesc.Count = 1;
dscd.SampleDesc.Quality = 0;
dscd.Scaling = DXGI_SCALING_NONE;
dscd.Stereo = FALSE;
dscd.SwapEffect = DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL;
dscd.Width = 640;
if (SUCCEEDED(hr)) {
OutputDebugString(L"DXGI Device created successful\n");
hr = D2D1CreateDevice(dxgiDevice, CreationProperties(D2D1_THREADING_MODE_SINGLE_THREADED, D2D1_DEBUG_LEVEL_NONE, D2D1_DEVICE_CONTEXT_OPTIONS_NONE), (ID2D1Device**)&d2dDevice);
}
if (SUCCEEDED(hr)) {
OutputDebugString(L"D2D Device created successful\n");
hr = d2dDevice->CreateDeviceContext(D2D1_DEVICE_CONTEXT_OPTIONS_NONE, (ID2D1DeviceContext**)&d2dDeviceContext);
}
if (SUCCEEDED(hr)) {
OutputDebugString(L"D2D Device Context created successful\n");
hr = CreateDXGIFactory2(DXGI_CREATE_FACTORY_DEBUG, __uuidof(IDXGIFactory2), (void**)&dxgiFactory);
}
if (SUCCEEDED(hr)) {
OutputDebugString(L"DXGI Factory created successful\n");
hr = dxgiFactory->CreateSwapChainForHwnd(d3dDevice, hWnd, &dscd, NULL, NULL, &dxgiSwapChain);
}
if (SUCCEEDED(hr)) {
OutputDebugString(L"DXGI Swap Chain created successful\n");
hr = dxgiSwapChain->GetBuffer(0, __uuidof(IDXGISurface), (void**)&dxgiBackBufferSurface);
}
if (SUCCEEDED(hr)) {
hr = d2dDeviceContext->CreateBitmapFromDxgiSurface(dxgiBackBufferSurface, BitmapProperties1(D2D1_BITMAP_OPTIONS_TARGET | D2D1_BITMAP_OPTIONS_CANNOT_DRAW, PixelFormat(DXGI_FORMAT_B8G8R8A8_UNORM, D2D1_ALPHA_MODE_IGNORE),0,0), &bmpTarget);
}
if (SUCCEEDED(hr)) {
OutputDebugString(L"D2D Bitmap created successful\n");
d2dDeviceContext->SetTarget(bmpTarget);
hr = d2dDeviceContext->CreateSolidColorBrush(ColorF(ColorF::White), &shapeBr);
}
if (SUCCEEDED(hr)) {
OutputDebugString(L"D2D Solid Color Brush created successful\n");
d2dDeviceContext->SetUnitMode(D2D1_UNIT_MODE_PIXELS);
d2dDeviceContext->SetTransform(Matrix3x2F::Identity());
d2dDeviceContext->SetAntialiasMode(D2D1_ANTIALIAS_MODE::D2D1_ANTIALIAS_MODE_ALIASED);
}
while (msg.message != WM_QUIT) {
if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
else {
d2dDeviceContext->BeginDraw();
d2dDeviceContext->Clear(ColorF(ColorF::ForestGreen));
d2dDeviceContext->DrawLine(Point2F(400, 0), Point2F(400, 400), shapeBr);
d2dDeviceContext->DrawLine(Point2F(200.0f, 320.0f), Point2F(400.0f, 320.0f), shapeBr);
d2dDeviceContext->DrawEllipse(D2D1::Ellipse(Point2F(300.0f, 300.0f), 10.0f, 10.0f), shapeBr);
POINT cursorPos;
GetCursorPos(&cursorPos);
ScreenToClient(hWnd,&cursorPos);
wstring dbgCursorPos = wstring(L"(MouseX: " + to_wstring(cursorPos.x) + L" MouseY: " + to_wstring(cursorPos.y) + L")\n");
OutputDebugString(dbgCursorPos.c_str());
d2dDeviceContext->EndDraw();
dxgiSwapChain->Present(1, 0);
}
}
SafeRelease(&d3dDevice);
SafeRelease(&dxgiBackBufferSurface);
SafeRelease(&dxgiDevice);
SafeRelease(&dxgiFactory);
SafeRelease(&dxgiSwapChain);
SafeRelease(&d2dDevice);
SafeRelease(&d2dDeviceContext);
SafeRelease(&bmpTarget);
SafeRelease(&shapeBr);
return 0;
}
template<typename Interface> void SafeRelease(Interface** ppInterface) {
if (*ppInterface) {
(*ppInterface)->Release();
(*ppInterface) = NULL;
}
}
LRESULT CALLBACK WndProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam) {
if (Msg == WM_DESTROY) {
PostQuitMessage(0);
return 0;
}
return DefWindowProc(hWnd, Msg, wParam, lParam);
}
I am using ISpVoice to speak an input string. Now, even though I use SPF_ASYNC and SPF_PURGEBEFORESPEAK tags in the Speak method, the tts doesn't stop whenever Pause is called instead it continues until the tts finishes a word.
Here's how I do it:
void speakSentence()
{
pVoice->Pause();
pVoice->Speak(L"This is a sentence.", SPF_ASYNC | SPF_PURGEBEFORESPEAK, NULL);
pVoice->Resume();
}
Whenever I try to call this function at the middle of the word "sentence", the tts doesn't pause and instead continues to say the word until the end.
From microsoft documentation:
ISpVoice::Pause pauses the voice at the nearest alert boundary and closes the output device, allowing access to pending speak requests from other voices.
I tried changing the alert boundary by:
pVoice->SetAlertBoundary(SPEI_PHONEME);
and it doesn't work.
There is NVDA Screen Reader that solved this problem but I don't know how they did it.
Is there anyway to solve my problem?
EDIT:
Here's my full code. I am creating a small screen reader program that uses both UIAutomation and MSAA.
The program may somewhat unstable when comparing UI objects but most times it works.
screeenreader.h:
#ifndef _SCREENREADER_H_
#define _SCREENREADER_H_
#define WIN32_LEAN_AND_MEAN
#ifndef UNICODE
#define UNICODE
#endif
#include <windows.h>
#include <memory>
#include "speechsynthesis.h"
#include "uiautomator.h"
class ScreenReader
{
public:
explicit ScreenReader(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR pScmdline, int iCmdShow);
virtual ~ScreenReader();
LRESULT CALLBACK MessageHandler(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
int Exec();
private:
void InitializeWindows();
void InitRawInputDevices();
bool IsMouseMove();
private:
LPCWSTR m_applicationName;
HINSTANCE m_hInstance;
HINSTANCE m_hPrevInstance;
PSTR m_pScmdline;
int m_iCmdShow;
HWND m_hWnd;
SpeechSynthesis *m_pSpeech;
UIAutomator *m_pAutomator;
RAWINPUTDEVICE rid[2];
LONG m_prevMouseX;
LONG m_prevMouseY;
BSTR currItem;
};
static ScreenReader *application;
static LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
#endif
screenreader.cpp: In this part I called ISpVoice at the messageloop section. At ScreenReader::MessageHandler() function at IsMouseMove condition.
#include "screenreader.h"
ScreenReader::ScreenReader(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR pScmdline, int iCmdShow)
{
CoInitialize(NULL);
m_pSpeech = new SpeechSynthesis;
m_pAutomator = new UIAutomator;
// Get current Cursor position.
POINT pt;
GetCursorPos(&pt);
m_prevMouseX = pt.x;
m_prevMouseY = pt.y;
// Notify user the program is loading.
m_pSpeech->Speak(L"Loading Rescan. Please wait.", SPF_DEFAULT, NULL);
m_hInstance = hInstance;
m_hPrevInstance = hPrevInstance;
m_pScmdline = pScmdline;
m_iCmdShow = iCmdShow;
application = this;
InitializeWindows();
InitRawInputDevices();
}
ScreenReader::~ScreenReader()
{
if (m_pSpeech != nullptr)
{
delete m_pSpeech;
m_pSpeech = nullptr;
}
if (m_pAutomator != nullptr)
{
delete m_pAutomator;
m_pAutomator = nullptr;
}
if (currItem != NULL)
{
SysFreeString(currItem);
currItem = NULL;
}
CoUninitialize();
}
LRESULT CALLBACK ScreenReader::MessageHandler(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_INPUT:
{
UINT dwSize;
GetRawInputData(
(HRAWINPUT)lParam,
RID_INPUT,
NULL,
&dwSize,
sizeof(RAWINPUTHEADER)
);
std::unique_ptr<BYTE[]> lpb(new BYTE[dwSize]);
if (!lpb)
return 0;
if (GetRawInputData(
(HRAWINPUT)lParam,
RID_INPUT,
lpb.get(),
&dwSize,
sizeof(RAWINPUTHEADER)
) != dwSize)
OutputDebugString(L"GetRawInputData does not return correct size!\n");
RAWINPUT *raw = (RAWINPUT*)lpb.get();
if (raw->header.dwType == RIM_TYPEKEYBOARD)
{
UINT mess = raw->data.keyboard.Message;
UINT vKey = raw->data.keyboard.VKey;
if (mess == WM_KEYDOWN)
{
}
}
else if (raw->header.dwType == RIM_TYPEMOUSE)
{
if (IsMouseMove())
{
BSTR item;
HRESULT hr = m_pAutomator->GetUIAutomationItemNameAtMousePoint(&item);
if (item == NULL)
return 0;
if (currItem == NULL)
currItem = SysAllocString(item);
if (wcscmp(currItem, item) != 0)
{
m_pSpeech->Stop();
m_pSpeech->Speak(item);
if (currItem != NULL)
SysFreeString(currItem);
currItem = SysAllocString(item);
}
SysFreeString(item);
}
}
}
return 0;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
}
int ScreenReader::Exec()
{
MSG msg;
ShowWindow(m_hWnd, m_iCmdShow);
// Tell the user that the program is ready.
m_pSpeech->Speak(L"Rescan ready.", SPF_PURGEBEFORESPEAK);
// The message loop
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}
void ScreenReader::InitializeWindows()
{
// Create Window class.
WNDCLASSEX wc;
m_applicationName = L"Rescan Screen Reader";
wc.cbSize = sizeof(WNDCLASSEX);
wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
wc.lpfnWndProc = WndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = m_hInstance;
wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
wc.lpszMenuName = NULL;
wc.lpszClassName = m_applicationName;
wc.hIconSm = wc.hIcon;
// Register the window class.
RegisterClassEx(&wc);
m_hWnd = CreateWindowEx(
WS_EX_OVERLAPPEDWINDOW,
m_applicationName,
L"Rescan Screen Reader",
WS_CAPTION | WS_MINIMIZEBOX | WS_OVERLAPPED | WS_SYSMENU,
(GetSystemMetrics(SM_CXSCREEN) - 500) / 2,
(GetSystemMetrics(SM_CYSCREEN) - 300) / 2,
500,
300,
NULL,
NULL,
m_hInstance,
NULL
);
}
void ScreenReader::InitRawInputDevices()
{
// Initialize Keyboard
rid[0].usUsagePage = 0x01;
rid[0].usUsage = 0x06;
rid[0].dwFlags = RIDEV_INPUTSINK;
rid[0].hwndTarget = m_hWnd;
// Initialize Mouse
rid[1].usUsagePage = 0x01;
rid[1].usUsage = 0x02;
rid[1].dwFlags = RIDEV_INPUTSINK;
rid[1].hwndTarget = m_hWnd;
// Register RIDs
RegisterRawInputDevices(rid, 2, sizeof(RAWINPUTDEVICE));
}
bool ScreenReader::IsMouseMove()
{
POINT pt;
GetCursorPos(&pt);
bool result = !(m_prevMouseX == pt.x && m_prevMouseY == pt.y);
m_prevMouseX = pt.x;
m_prevMouseY = pt.y;
return result;
}
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_QUIT:
PostQuitMessage(0);
return 0;
case WM_DESTROY:
PostQuitMessage(0);
return 0;
default:
return application->MessageHandler(hWnd, message, wParam, lParam);
}
}
I wrapped ISpVoice into the SpeechSynthesis class.
speechsynthesis.h:
#ifndef _SPEECHSYNTHESIS_H_
#define _SPEECHSYNTHESIS_H_
#pragma warning(disable : 4996)
#define SPCAT_VOICES_ONECORE L"HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Speech_OneCore\\Voices"
#include <sapi.h>
#include <sphelper.h>
#include <atlbase.h>
class SpeechSynthesis
{
public:
SpeechSynthesis();
~SpeechSynthesis();
HRESULT Speak(LPCWSTR pwcs, DWORD dwFlags = SPF_PURGEBEFORESPEAK | SPF_ASYNC | SPF_IS_NOT_XML, ULONG *pulStreamNumber = NULL);
HRESULT Resume();
HRESULT Pause();
HRESULT Stop();
ISpVoice* getVoice();
private:
CComPtr<ISpObjectToken> cpVoiceToken;
CComPtr<IEnumSpObjectTokens> cpEnum;
ISpVoice* pVoice;
ULONG count;
};
#endif
speechsynthesis.cpp:
#include "speechsynthesis.h"
SpeechSynthesis::SpeechSynthesis()
{
HRESULT hr = CoCreateInstance(CLSID_SpVoice, NULL, CLSCTX_ALL, IID_ISpVoice, (void **)&pVoice);
if (SUCCEEDED(hr))
hr = SpEnumTokens(SPCAT_VOICES_ONECORE, NULL, NULL, &cpEnum);
if (SUCCEEDED(hr))
hr = cpEnum->GetCount(&count);
if (SUCCEEDED(hr))
{
cpEnum->Item(1, &cpVoiceToken);
pVoice->SetPriority(SPVPRIORITY::SPVPRI_ALERT);
pVoice->SetAlertBoundary(SPEI_PHONEME);
pVoice->SetOutput(NULL, TRUE);
pVoice->SetVoice(cpVoiceToken);
}
if (FAILED(hr))
{
MessageBox(NULL, "A fatal error has occured", "Error Message", MB_ABORTRETRYIGNORE);
}
}
SpeechSynthesis::~SpeechSynthesis()
{
pVoice->Release();
}
HRESULT SpeechSynthesis::Speak(LPCWSTR pwcs, DWORD dwFlags, ULONG *pulStreamNumber)
{
return pVoice->Speak(pwcs, dwFlags, pulStreamNumber);
}
HRESULT SpeechSynthesis::Resume()
{
return pVoice->Resume();
}
HRESULT SpeechSynthesis::Pause()
{
return pVoice->Pause();
}
HRESULT SpeechSynthesis::Stop()
{
return Speak(NULL);
}
ISpVoice * SpeechSynthesis::getVoice()
{
return pVoice;
}
uiautomator.h
#ifndef _UIAUTOMATOR_H_
#define _UIAUTOMATOR_H_
#include <windows.h>
#include <oleacc.h>
#include <uiautomation.h>
#pragma comment(lib, "oleacc.lib")
class UIAutomator
{
public:
UIAutomator();
~UIAutomator();
HRESULT GetItemNameAtMousePoint(BSTR *pStr);
HRESULT GetUIAutomationItemNameAtMousePoint(BSTR *pStr);
private:
HRESULT InitUIAutomation();
private:
IUIAutomation *m_automation;
};
#endif
uiautomator.cpp
#include "uiautomator.h"
UIAutomator::UIAutomator()
{
SetProcessDPIAware();
HRESULT hr = InitUIAutomation();
}
UIAutomator::~UIAutomator()
{
}
HRESULT UIAutomator::GetItemNameAtMousePoint(BSTR * pStr)
{
POINT pt;
GetPhysicalCursorPos(&pt);
VARIANT varItem;
IAccessible *pAcc;
HRESULT hr = AccessibleObjectFromPoint(pt, &pAcc, &varItem);
if (SUCCEEDED(hr))
{
hr = pAcc->get_accName(varItem, pStr);
VariantClear(&varItem);
pAcc->Release();
}
return hr;
}
HRESULT UIAutomator::GetUIAutomationItemNameAtMousePoint(BSTR * pStr)
{
CONTROLTYPEID id;
POINT pt;
IUIAutomationElement *elem;
VARIANT val;
GetCursorPos(&pt);
HRESULT hr = m_automation->ElementFromPoint(pt, &elem);
if (SUCCEEDED(hr))
{
hr = elem->get_CurrentControlType(&id);
if (SUCCEEDED(hr))
{
if (id == UIA_PaneControlTypeId)
GetItemNameAtMousePoint(pStr);
else if (id == UIA_EditControlTypeId)
{
hr = elem->GetCurrentPropertyValue(UIA_ValueValuePropertyId, &val);
if (SUCCEEDED(hr))
{
*pStr = SysAllocString(val.bstrVal);
VariantClear(&val);
}
}
else
{
hr = elem->get_CurrentName(pStr);
}
}
elem->Release();
}
return hr;
}
HRESULT UIAutomator::InitUIAutomation()
{
HRESULT hr = CoCreateInstance(__uuidof(CUIAutomation), NULL, CLSCTX_INPROC_SERVER,
__uuidof(IUIAutomation), (void**)&m_automation);
return hr;
}
main.cpp
#include "vld.h"
#include "screenreader.h"
#include <memory>
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR pScmdline, int iCmdShow)
{
std::unique_ptr<ScreenReader> app(new ScreenReader(hInstance, hPrevInstance, pScmdline, iCmdShow));
return app->Exec();
}
If you don't have time to compile here's the program.
If you launch it and hover the mouse on the program window there is a lag when highlighting minimize and close button. Also sometimes the tts doesn't stop immediately when you hover at another object.
Compare this one to NVDA Screen Reader. You will notice the big difference.
It works for me with or without setting SetAlertBoundary(SPEI_PHONEME).
The following is my test code, you can have a try.
HRESULT hr = ::CoInitialize(nullptr);
if (FAILED(hr))
{
return EXIT_FAILURE;
}
std::wstring text;
text = L"This is a sentence.";
CComPtr<ISpVoice> cpVoice;
// Create a SAPI voice
hr = cpVoice.CoCreateInstance(CLSID_SpVoice);
//cpVoice->SetAlertBoundary(SPEI_PHONEME);
// set the output to the default audio device
if (SUCCEEDED(hr))
{
hr = cpVoice->SetOutput(NULL, TRUE);
}
// Speak the text
if (SUCCEEDED(hr))
{
hr = cpVoice->Speak(text.c_str(), SPF_ASYNC | SPF_PURGEBEFORESPEAK, NULL);
}
text = L"The third type, a logarithm of the unsigned fold change, is undoubtedly the most tractable.";
Sleep(600);
hr = cpVoice->Pause();
hr = cpVoice->Resume();
hr = cpVoice->Speak(text.c_str(), SPF_ASYNC | SPF_PURGEBEFORESPEAK, NULL);
Sleep(10000);
::CoUninitialize();
if (SUCCEEDED(hr))
{
return EXIT_SUCCESS;
}
return EXIT_FAILURE;
I finally got it!
CComPtr<ISpAudio> audio;
CSpStreamFormat format;
format.AssignFormat(SPSF_11kHz8BitMono);
Initialize audio
SpCreateDefaultObjectFromCategoryId(SPCAT_AUDIOOUT, &audio);
Then, set its format and set it as output to pVoice.
audio->SetFormat(format.FormatId(), format.WaveFormatExPtr());
pVoice->SetOutput(audio, FALSE);
Now I have access to the audio stream!
Now to Immediately stop the audio, call:
audio->SetState(SPAS_STOP, 0);
Then speak again using:
audio->SetState(SPAS_RUN, 0);
pVoice->Speak(L"This is a sentence", SPF_ASYNC | SPF_PURGEBEFORESPEAK, NULL);
I want to get a fast access to the pixels of a game which uses directX9 or 10. Therefore I used the D3D9 library. Do I have to use the D3D10 library when it is a directX10 game? If this is true, the next part is irrelevant.
The following code works except I'm only get zeros in qDebug("%.2f, %.2f, %.2f, %.2f", pixel[0].r, pixel[0].g, pixel[0].b, pixel[0].a); although it should have an other color and I have no clue why. Is there an error in swapping the data?
Initialization:
IDirect3D9 *m_d3d;
IDirect3DDevice9 *m_d3ddev;
D3DDISPLAYMODE *m_d3ddm;
HRESULT hr;
m_d3d = Direct3DCreate9(D3D_SDK_VERSION);
if (m_d3d == NULL)
{
qFatal("Cannot create Direct3D!");
}
m_d3ddm = (D3DDISPLAYMODE *)calloc(1, sizeof(D3DDISPLAYMODE));
hr = m_d3d->GetAdapterDisplayMode(D3DADAPTER_DEFAULT, m_d3ddm);
if (hr != D3D_OK)
{
m_d3d->Release();
qFatal("Cannot get DisplayMode!");
}
D3DPRESENT_PARAMETERS d3dpp;
ZeroMemory(&d3dpp, sizeof(d3dpp));
d3dpp.Windowed = TRUE;
d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
d3dpp.hDeviceWindow = m_target;
d3dpp.BackBufferWidth = m_d3ddm->Width;
d3dpp.BackBufferHeight = m_d3ddm->Height;
d3dpp.BackBufferFormat = m_d3ddm->Format;
hr = m_d3d->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, m_target, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &m_d3ddev);
if (FAILED(hr))
{
m_d3d->Release();
qFatal("Failed CreateDevice!");
}
else
{
qDebug("Created Device with %i * %i", m_d3ddm->Width, m_d3ddm->Height);
}
Capture:
IDirect3DSurface9 *renderTarget= NULL;
IDirect3DSurface9 *destTarget = NULL;
hr = m_d3ddev->GetRenderTarget(0, &renderTarget);
if (FAILED(hr))
{
qFatal("Failed GetRenderTarget!");
}
hr = m_d3ddev->CreateOffscreenPlainSurface(m_d3ddm->Width, m_d3ddm->Height, m_d3ddm->Format, D3DPOOL_SYSTEMMEM, &destTarget, NULL);
if (FAILED(hr))
{
qFatal("Failed CreateOffscreenPlainSurface!");
}
hr = m_d3ddev->GetRenderTargetData(renderTarget, destTarget);
if (FAILED(hr))
{
qFatal("Failed GetRenderTargetData!");
}
D3DLOCKED_RECT lr;
ZeroMemory(&lr, sizeof(D3DLOCKED_RECT));
hr = destTarget->LockRect(&lr, 0, D3DLOCK_READONLY);
if (FAILED(hr))
{
qFatal("Cannot lock rect!");
}
ARGB *pixel = (ARGB *)lr.pBits;
if (!pixel)
{
qFatal("No data!");
}
qDebug("%.2f, %.2f, %.2f, %.2f", pixel[0].r, pixel[0].g, pixel[0].b, pixel[0].a);
hr = destTarget->UnlockRect();
if (FAILED(hr))
{
qFatal("Cannot unlock rect!");
}
renderTarget->Release();
destTarget->Release();
Cleaning
m_d3ddev->Release();
m_d3d->Release();
delete m_d3ddm;
delete m_d3d;
delete m_d3ddev;
This code is a simulation of what you should have.. It shows that the backbuffer is actually being captured. I created the device the exact same way you did. I capture the back-buffer the same way..
To test if the back-buffer is actually captured, I have set the window background to a navy-blue colour. Then when I call the capture function, I compare all the colours in the buffer to the original background colour.. This lets me know if a single pixel is different than the background..
If it is different, we "possibly" failed to capture the background. Otherwise, we are good..
I've tested the below and it indeed captures the backbuffer perfectly fine.. I even saved the backbuffer to a bitmap to see if it captures it and it does..
All in all, there's nothing wrong with your code, but I cannot guarantee that you are using it correctly.. In other words, you haven't shown me where you call your back-buffer capture code.. There are many places it can be called, but the best places are either in a hook to EndScene or a hook to Present. If you are using this on your own application, then call it in your onDraw/onUpdate function..
#include <tchar.h>
#include <windows.h>
#include <d3d9.h>
#include <d3dx9.h>
#include <iostream>
HRESULT capture(IDirect3DDevice9* m_d3ddev, void* buffer, int& width, int& height, D3DFORMAT format);
void onUpdate(HWND hwnd, IDirect3D9* d3d9, IDirect3DDevice9* d3ddev9, D3DFORMAT format)
{
d3ddev9->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0, 40, 100), 1.0f, 0);
d3ddev9->BeginScene();
//All drawing goes here..
d3ddev9->EndScene();
d3ddev9->Present(NULL, NULL, NULL, NULL); //Swaps the back and front buffers. Displays all drawing on the screen..
RECT rect;
GetClientRect(hwnd, &rect);
int width = rect.right - rect.left, height = rect.bottom - rect.top;
unsigned char* buffer = new unsigned char[width * height * 4];
capture(d3ddev9, buffer, width, height, format);
unsigned char* px = buffer;
for(int i = 0; i < height; ++i)
{
for(int j = 0; j < width; ++j)
{
unsigned char B = *px++;
unsigned char G = *px++;
unsigned char R = *px++;
unsigned char A = *px++;
if(D3DCOLOR_XRGB(R, G, B) != D3DCOLOR_XRGB(0, 40, 100))
{
MessageBox(NULL, "FAILED.. Colour differs from original background..", NULL, 0);
}
}
}
delete[] buffer;
}
int onDisplay(HWND hwnd)
{
IDirect3D9* d3d9 = NULL;
IDirect3DDevice9* d3ddev9 = NULL;
D3DPRESENT_PARAMETERS Parameters = {0};
d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
D3DDISPLAYMODE* dispMode = new D3DDISPLAYMODE();
d3d9->GetAdapterDisplayMode(D3DADAPTER_DEFAULT, dispMode);
Parameters.Windowed = true;
Parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
Parameters.hDeviceWindow = hwnd;
Parameters.BackBufferFormat = dispMode->Format;
d3d9->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hwnd, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &Parameters, &d3ddev9);
delete dispMode;
MSG messages;
ShowWindow(hwnd, SW_SHOW);
while(true)
{
if(PeekMessage(&messages, NULL, 0, 0, PM_REMOVE) > 0)
{
if(messages.message != WM_QUIT)
{
TranslateMessage(&messages);
DispatchMessageW(&messages);
continue;
}
break;
}
else
{
onUpdate(hwnd, d3d9, d3ddev9, Parameters.BackBufferFormat);
}
}
if(d3ddev9) d3ddev9->Release();
if(d3d9) d3d9->Release();
return messages.wParam;
}
LRESULT CALLBACK WindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch(message)
{
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hwnd, message, wParam, lParam);
}
return 0;
}
int WINAPI WinMain(HINSTANCE hThisInstance, HINSTANCE hPrevInstance, LPSTR lpszArgument, int nCmdShow)
{
WNDCLASSEX wincl;
wincl.hInstance = hThisInstance;
wincl.lpszClassName = "D3DWindow";
wincl.lpfnWndProc = WindowProcedure;
wincl.style = CS_DBLCLKS;
wincl.cbSize = sizeof(WNDCLASSEX);
wincl.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wincl.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
wincl.hCursor = LoadCursor(NULL, IDC_ARROW);
wincl.lpszMenuName = NULL;
wincl.cbClsExtra = 0;
wincl.cbWndExtra = 0;
wincl.hbrBackground = (HBRUSH) COLOR_BACKGROUND;
if(!RegisterClassEx(&wincl)) return 0;
HWND hwnd = CreateWindowEx(0, "D3DWindow", "D3D9: Window", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 544, 375, HWND_DESKTOP, NULL, hThisInstance, NULL);
return onDisplay(hwnd);
}
HRESULT capture(IDirect3DDevice9* m_d3ddev, void* buffer, int& width, int& height, D3DFORMAT format)
{
IDirect3DSurface9 *renderTarget= NULL;
IDirect3DSurface9 *destTarget = NULL;
HRESULT hr = m_d3ddev->GetRenderTarget(0, &renderTarget);
hr = m_d3ddev->CreateOffscreenPlainSurface(width, height, format, D3DPOOL_SYSTEMMEM, &destTarget, NULL);
if(FAILED(hr))
{
printf("Failed CreateOffscreenPlainSurface!");
}
hr = m_d3ddev->GetRenderTargetData(renderTarget, destTarget);
if(FAILED(hr))
{
printf("Failed GetRenderTargetData!");
}
D3DLOCKED_RECT lr;
ZeroMemory(&lr, sizeof(D3DLOCKED_RECT));
hr = destTarget->LockRect(&lr, 0, D3DLOCK_READONLY);
if(FAILED(hr))
{
printf("Cannot lock rect!");
}
if(lr.pBits)
{
memcpy(buffer, lr.pBits, width * height * 4);
}
hr = destTarget->UnlockRect();
if(FAILED(hr))
{
printf("Cannot unlock rect!");
}
renderTarget->Release();
destTarget->Release();
return hr;
}
I have just started learning DirectX, and I am trying to implement it with the use of the C++ language. I have started reading a book about this problem, named Beginning DirectX 10 Game Programming. Nevermind, I am running in to a problem. I have added the needed libraries and have included the necessary files with Visual Studio. The error is as follow:
Error 26 error LNK2019: unresolved external symbol "bool __cdecl InitDirect3D(struct HWND__ *,int,int)" (?InitDirect3D##YA_NPAUHWND__##HH#Z) referenced in function _WinMain#16 C:\Users\Robert\documents\visual studio 2013\Projects\DirectXBook\exampleWithDirectX1\SourceCode.obj exampleWithDirectX1
Error 27 error LNK1120: 1 unresolved externals C:\Users\Robert\documents\visual studio 2013\Projects\DirectXBook\Debug\exampleWithDirectX1.exe 1 1 exampleWithDirectX1
#include <Windows.h>
#include <tchar.h>
#include <d3d10.h>
#include <d3dx10.h>
#pragma comment (lib, "d3dx10.lib")
#pragma comment (lib, "d3d10.lib")
HINSTANCE hInstance; //Instanszkezelo
HWND hWnd; //Ablakkezelo
ID3D10Device *pD3DDevice = NULL;
IDXGISwapChain *pSwapChain = NULL;
ID3D10RenderTargetView *pRenderTargetView = NULL;
int width = 640;
int height = 480;
//fuggveny prototipusok definialasa
bool InitWindow(HINSTANCE hInstance, int width, int height);
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
bool InitDirect3D(HWND hWnd, int width, int height);
void Render();
void shutDownDirect3D();
//WinMain, belepopont a windows applikacioba
int WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdline, int nCmdShow){
//ablakinicalizalas
if (!InitWindow(hInstance, width, height)){
return false;
}
if (!InitDirect3D(hWnd, width, height)){
return 0;
}
//main message loop
MSG msg = { 0 };
while (WM_QUIT != msg.message){
while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE) == TRUE){
TranslateMessage(&msg);
DispatchMessage(&msg);
}
//renderelest kezelo fuggveny meghivasa
Render();
}
shutDownDirect3D();
return msg.wParam;
}
bool InitWindow(HINSTANCE hInstance, int width, int height){
WNDCLASSEX wcex;
// WNDCLASSEX wcex objektum kitoltese
// meghatarozza, hogyan fog kinezni az ablakunk
wcex.cbSize = sizeof(WNDCLASSEX); // struktura merete
wcex.style = CS_HREDRAW | CS_VREDRAW; // az osztaly tipusa
wcex.lpfnWndProc = (WNDPROC)WndProc; // az ablak procedure visszahivas (callback)
wcex.cbClsExtra = 0; // extra byteok lefoglasasa az osztalynak
wcex.cbWndExtra = 0; // extra bytes to allocate for this instance
wcex.hInstance = hInstance; // kezelo az applikacios esemenynek
wcex.hIcon = 0; // applikaciohoz hozzarendelendo ikon
wcex.hCursor = LoadCursor(NULL, IDC_ARROW); // kurzor hasznalatanak definialasa
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1); // hatterszin
wcex.lpszMenuName = NULL; // eroforrsanev a menunek
wcex.lpszClassName = TEXT("DirectXExample"); // az osztalynev letrehozva
wcex.hIconSm = 0; // kezelo a kisikonhoz
RegisterClassEx(&wcex); //wcex objektum regisztralasa
RECT rect = { 0, 0, width, height }; // ablakatmeretezes
AdjustWindowRect(&rect, WS_OVERLAPPEDWINDOW, FALSE);
// ablak letrehozasa a felso osztalybol
hWnd = CreateWindow(TEXT("DirectXExample"),
TEXT("DirectXExample"),
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
CW_USEDEFAULT,
rect.right - rect.left,
rect.bottom - rect.top,
NULL,
NULL,
hInstance,
NULL);
if (!hWnd){
return false;
}
// ablak kirajzoalsa a kijelzore
ShowWindow(hWnd, SW_SHOW);
UpdateWindow(hWnd);
return true;
}
//WPARAM == typedef UINT_PTR WPARAM passing and returning polymorphic values
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam){
//megnézi, hogy van - e üzenet a sorban
switch (message){
case WM_KEYDOWN:
switch (wParam){
//ha a felhasznalo az escape billentyu megnyomja kilepes
case VK_ESCAPE:
PostQuitMessage(0);
break;
}
//ha a felhasznalo az X gombra kattint kilepes
case WM_DESTROY:
PostQuitMessage(0);
break;
}
//uzenet elkuldese az alapveto ablak proceduranak, hogy az tovabb elemezze
return DefWindowProc(hWnd, message, wParam, lParam);
}
bool InitDirect3d(HWND hWnd, int width, int height){
// Create and clear the DXGI_SWAP_CHAIN_DESC structure
DXGI_SWAP_CHAIN_DESC swapChainDesc;
ZeroMemory(&swapChainDesc, sizeof(swapChainDesc));
// Fill in the needed values
swapChainDesc.BufferCount = 1;
swapChainDesc.BufferDesc.Width = width;
swapChainDesc.BufferDesc.Height = height;
swapChainDesc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
swapChainDesc.BufferDesc.RefreshRate.Numerator = 60;
swapChainDesc.BufferDesc.RefreshRate.Denominator = 1;
swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
swapChainDesc.OutputWindow = hWnd;
swapChainDesc.SampleDesc.Count = 1;
swapChainDesc.SampleDesc.Quality = 0;
swapChainDesc.Windowed = TRUE;
// Create the D3D device and the swap chain
HRESULT hr = D3D10CreateDeviceAndSwapChain(NULL,
D3D10_DRIVER_TYPE_REFERENCE,
NULL,
0,
D3D10_SDK_VERSION,
&swapChainDesc,
&pSwapChain,
&pD3DDevice);
// Error checking. Make sure the device was created
if (hr != S_OK){
return false;
}
// Get the back buffer from the swapchain
ID3D10Texture2D *pBackBuffer;
hr = pSwapChain->GetBuffer(0, __uuidof(ID3D10Texture2D), (LPVOID*)
&pBackBuffer);
if (hr != S_OK){
return false;
}
// create the render target view
hr = pD3DDevice->CreateRenderTargetView(pBackBuffer, NULL, &pRenderTargetView);
// release the back buffer
pBackBuffer->Release();
// Make sure the render target view was created successfully
if (hr != S_OK){
return false;
}
// set the render target
pD3DDevice->OMSetRenderTargets(1, &pRenderTargetView, NULL);
// create and set the viewport
D3D10_VIEWPORT viewPort;
viewPort.Width = width;
viewPort.Height = height;
viewPort.MinDepth = 0.0f;
viewPort.MaxDepth = 1.0f;
viewPort.TopLeftX = 0;
viewPort.TopLeftY = 0;
pD3DDevice->RSSetViewports(1, &viewPort);
return true;
}
void Render(){
if (pD3DDevice != NULL){
//a celpuffer tisztitasa
pD3DDevice->ClearRenderTargetView(pRenderTargetView, D3DXCOLOR(0.0f, 0.0f, 0.0f, 0.0f));
//IDE JON A RAJZOLAS
//a kovetkezo elem kijelzese a SwapChain - bol
pSwapChain->Present(0, 0);
}
}
void shutDownDirect3D(){
//release the rendertarget
if (pRenderTargetView){
pRenderTargetView->Release();
}
if (pSwapChain){
pSwapChain->Release();
}
if (pD3DDevice){
pD3DDevice->Release();
}
}
Thanks in advance!
And where is this function
bool InitDirect3D(HWND hWnd, int width, int height);
defined?
You defined it as InitDirect3d instead of InitDirect3D that is instead of 'd' you should write 'D'
Why do simple old programs like this that I've had lying around for years sometimes set off my anti-virus? It picked up the compiled exe for this one and said it might be a gen/dropper or something like that.
Here's the code:
#include "c:\\dxsdk\\include\\d3d9.h"
#include "c:\\dxsdk\\include\\d3dx9.h"
#include <time.h>
#include <sstream>
using namespace std;
#define APPTITLE "DirectX Practice"
LRESULT CALLBACK WinProc(HWND,UINT,WPARAM,LPARAM);
int Initialize(HWND);
void OnCleanup(HWND);
void OnInterval(HWND);
BOOL KEY_DOWN(UINT);
BOOL KEY_UP(UINT);
LPDIRECT3D9 d3d = NULL;
LPDIRECT3DDEVICE9 d3ddev = NULL;
LPDIRECT3DSURFACE9 backBuffer = NULL;
LPDIRECT3DSURFACE9 surface = NULL;
UINT Screen_Width = 0;
UINT Screen_Height = 0;
int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nCmdShow)
{
//
MSG msg;
////////////
Screen_Width = 1280;//GetSystemMetrics(SM_CXFULLSCREEN);
Screen_Height= 800;//GetSystemMetrics(SM_CYFULLSCREEN);
// can't use the real rez if it isn't standard
if( Screen_Width==0 || Screen_Height==0 ){
MessageBox(
NULL,
"Could not detect native screen resolution. Using Default.",
"Error",
MB_ICONERROR|MB_SYSTEMMODAL);
Screen_Width = 800;
Screen_Height = 600;
}
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)GetSysColorBrush(COLOR_BTNFACE);
wc.lpszMenuName = NULL;
wc.lpszClassName = APPTITLE;
wc.hIconSm = NULL;
if(!RegisterClassEx(&wc))
return FALSE;
HWND hwnd;
hwnd = CreateWindow(
APPTITLE,
APPTITLE,
WS_EX_TOPMOST|WS_VISIBLE|WS_POPUP,
CW_USEDEFAULT,
CW_USEDEFAULT,
Screen_Width,
Screen_Height,
NULL,
NULL,
hInstance,
NULL);
if(!hwnd)
return FALSE;
ShowWindow(hwnd,SW_SHOW/*nCmdShow*/);
UpdateWindow(hwnd);
if(!Initialize(hwnd))
return FALSE;
int done = 0;
while( !done )
{
if(PeekMessage(&msg,NULL,0,0,PM_REMOVE))
{
if(msg.message==WM_QUIT)
{
MessageBox(hwnd,"Exiting","Notice",MB_OK|MB_SYSTEMMODAL);
done = 1;
}
TranslateMessage(&msg);
DispatchMessage(&msg);
}else{
OnInterval(hwnd);
}
}
return msg.wParam;
}
LRESULT CALLBACK WinProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch(msg)
{
case WM_DESTROY:
OnCleanup(hwnd);
PostQuitMessage(0);
return 0;
default:
return DefWindowProc(hwnd,msg,wParam,lParam);
}
return 0;
}
int Initialize(HWND hwnd)
{
d3d = Direct3DCreate9(D3D_SDK_VERSION);
if(d3d == NULL){
MessageBox(hwnd,"Could not initialize Direct3D 9","Error",MB_ICONERROR|MB_SYSTEMMODAL);
return 0;
}
D3DPRESENT_PARAMETERS dp;
ZeroMemory(&dp,sizeof(dp));
dp.Windowed = FALSE;
dp.SwapEffect = D3DSWAPEFFECT_DISCARD;
dp.BackBufferFormat = D3DFMT_X8R8G8B8;
dp.BackBufferCount = 1;
dp.BackBufferWidth = Screen_Width;
dp.BackBufferHeight = Screen_Height;
dp.hDeviceWindow = hwnd;
d3d->CreateDevice(
D3DADAPTER_DEFAULT,
D3DDEVTYPE_HAL,
hwnd,
D3DCREATE_SOFTWARE_VERTEXPROCESSING,
&dp,
&d3ddev);
if(d3ddev == NULL){
MessageBox(hwnd,"Could not create Direct3D 9 device","Error",MB_ICONERROR|MB_SYSTEMMODAL);
return 0;
}
srand(time(NULL));
d3ddev->Clear(0,NULL,D3DCLEAR_TARGET,D3DCOLOR_XRGB(0,0,0),1.0f,0);
d3ddev->GetBackBuffer(0,0,D3DBACKBUFFER_TYPE_MONO,&backBuffer);
if(d3ddev->CreateOffscreenPlainSurface(
1294,614,
D3DFMT_X8R8G8B8,
D3DPOOL_DEFAULT,
&surface,
NULL) != D3D_OK )
{
MessageBox(hwnd,"Could not create off-screen data surface","Error",MB_ICONERROR|MB_SYSTEMMODAL);
return 0;
}
if(D3DXLoadSurfaceFromFile(
surface,
NULL,
NULL,
"green.jpg",
NULL,
D3DX_DEFAULT,
0,
NULL) != D3D_OK )
{
MessageBox(hwnd,"Could not load image","Error",0);
return 0;
}
return 1;
}
void OnCleanup(HWND hwnd)
{
MessageBox(hwnd,"exiting","bye",MB_ICONERROR|MB_SYSTEMMODAL);
if( surface!=NULL )
{
surface->Release();
}
if(d3ddev!=NULL)
{
d3ddev->Release();
}
if(d3d!=NULL)
{
d3d->Release();
}
}
void OnInterval(HWND hwnd)
{
/*RECT rect;
int r;
int g;
int b;
*/
if( KEY_DOWN(VK_ESCAPE) )
PostMessage(hwnd,WM_QUIT,0,0);
if(d3ddev == NULL)
return;
d3ddev->Clear(0,NULL,D3DCLEAR_TARGET,D3DCOLOR_XRGB(0,0,0),1.0f,0);
if(d3ddev->BeginScene())
{
/*r = rand()%255;
g = rand()%255;
b = rand()%255;
d3ddev->ColorFill(surface,NULL,D3DCOLOR_XRGB(r,g,b));
rect.left = rand()%Screen_Width/2;
rect.top = rand()%Screen_Height/2;
rect.right = rect.left + rand()%Screen_Width/2;
rect.bottom = rect.top + rand()%Screen_Height/2;
*/
// blit surface's contents to the screen into the
// target rect area
d3ddev->StretchRect(surface,NULL,backBuffer,&rect,D3DTEXF_NONE);
d3ddev->EndScene();
}
d3ddev->Present(NULL,NULL,NULL,NULL);
}
BOOL KEY_DOWN(UINT key)
{
return (BOOL)(GetAsyncKeyState(key) & 0x8000);
}
BOOL KEY_UP(UINT key)
{
return !((BOOL)(GetAsyncKeyState(key) & 0x8000));
}
What is setting off the virus scanner, and more precisely, what can I do to avoid that?
Check what happens when you recompile. If it the problem does not persist then it might be that some other process is tampering with your executable. Check why the virri scanner matches what pattern in your file and if your compiler really created that code (by dumping intermediate assembler of the compiler)
Hope that helps
I think it's a trend. There are only so much viruses an antivirus software can detect. So they started detecting a lot of false positives to remind the user how good the antivirus is and how lucky he is his computer was protected.
I also encounter this problem very often. Some users start complaining about false positives with an antivirus, I submit a report, an update is issued fixing the false positive and in a month the false positive is back.
The best solution is a digital signature. A digitally signed file comes with a guarantee that it's from a trusted source, so most antivirus applications don't report it as a problem. The downside is that you have to buy a code signing certificate.