I'm following a direct2d tutorial and when I compile the code I get an error that a function is obsolete and that I should replace it, I look for ways to replace the function with the solutions that visual studio gives me (before publishing in stackoverflow) but it doesn't work, or I don't know how to call them.
main.cpp
// 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 the window.
m_hwnd = CreateWindow(
L"D2DDemoApp",
L"Direct2D 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
);
error
1>------ Build started: Project: entt, Configuration: Debug x64 ------
1>Using triplet "x64-windows-static" from "C:\Users\Jule\vcpkg\installed\x64-windows-static\"
1>main.cpp
1>C:\Users\Jule\source\repos\entt\entt\main.cpp(154,27): error C4996: 'ID2D1Factory::GetDesktopDpi': Deprecated. Use DisplayInformation::LogicalDpi for Windows Store Apps or GetDpiForWindow for desktop apps.
1>Done building project "entt.vcxproj" -- FAILED.
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
tutorial: https://learn.microsoft.com/en-us/windows/win32/direct2d/direct2d-quickstart
I just went through this tutorial myself and ran into the same issue. The solution provided by #Julio Enrique in the comments is correct. However, I didn't realize at first he replaced both dpiX and dpiY with x, so it didn't work for me. As a result, I found an even simpler drop and replacement fix for this example tutorial. For others experiencing this issue, try the following fix:
// obtain the system DPI and use it to scale the window size.
FLOAT dpiX, dpiY;
// The following will return the current system DPI. This is the value used
// to create a window with the correct dimensions.
dpiX = (FLOAT) GetDpiForWindow (GetDesktopWindow ());
dpiY = dpiX;
// Create the window.
m_hwnd = CreateWindow(
L"D2DDemoApp",
L"Direct2D 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
);
hr = m_hwnd ? S_OK : E_FAIL;
if (SUCCEEDED(hr))
{
ShowWindow(m_hwnd, SW_SHOWNORMAL);
UpdateWindow(m_hwnd);
}
Also pointed out by #Julio Enrique, make sure to link the required Direct2D library (i.e. d2d1.lib) either in the Visual Studio linker options or via the following pragma:
#pragma comment(lib, "d2d1.lib")
Going forward, in order to prevent others from experiencing this issue in the future when reading the posted tutorial documentation, I have submitted a Pull Request to fix the documentation on the Microsoft website.
Related
I use GLFW and GLEW; the problem is vsync is enabled by default, how can I shut it down?
Windows 10
Visual C++ 2019
OpenGL 3.0
Once you've made your GL context current via glfwMakeContextCurrent() you can use glfwSwapInterval(0) to request that vsync be disabled:
int main( int, char** )
{
GLFWwindow* window;
glfwInit();
window = glfwCreateWindow( 640, 480, "GLFW", NULL, NULL );
glfwMakeContextCurrent( window );
glfwSwapInterval( 0 );
...
Note that this is only a request, since your GL implementation may not support the underlying swap interval extension or vsync may be forced 'on' at the driver/OS level.
I'd like to add my custom border rectangle to another application window like this:
I wrote this code by surfing from google but didn't help me:
HWND hWndX;
HRGN hRegX;
HDC hdc;
hWndX = FindWindow(NULL, "Untitled - Notepad");
hdc = GetDC(hWndX);
if (hWndX)
{
hRegX = CreateRectRgn(10, 10, 200, 200);
SetWindowLong(hWndX, GWL_STYLE, GetWindowLong(hWndX, GWL_STYLE));
SetWindowPos(hWndX, hWndX, 0, 0, 100, 100, SWP_FRAMECHANGED);
SetWindowRgn(hWndX, hRegX, true);
}
else
MessageBox(hWndX, "Cant find the window handle", "Error!", 0);
This kind of thing /might/ have worked in the old Win16/Windows 95 era, but these days, the OS protects one program from affecting the other. To change the border of another process, you will need to inject your code (as a dll) into the other process (assuming you have the correct security level). It's not that it is impossible, but it's not the sort of thing a beginner coder would be able to do.
Snoop, the spy utility, uses some powerful technique (probably some sort of reflection) to inspect a running WPF application. Most interesting is the fact, that Snnop is able to readout the entire object structure.
A few days ago I downloaded the Snoop source code and spent some time on studying the internal behavior. Unfortunately, I couldn't find out yet how Snoop is doing these things, so I hope that anybody can help me out.
At work I am currently writing a Coded UI Testing-Framework and it would be fantastic if I had access to the application's object structures because this would allow me to not only assert the UI state.
UPDATE:
This is the code needed:
string filePath = "WpfApp.exe";
AppDomain appDomain = AppDomain.CurrentDomain;
byte[] bytes = System.IO.File.ReadAllBytes(filePath);
Assembly ass = appDomain.Load(bytes);
ass.EntryPoint.Invoke(null, new object[] { });
IntPtr handle = Process.GetCurrentProcess().MainWindowHandle;
Window w = System.Windows.Interop.HwndSource.FromHwnd(handle).RootVisual as Window;
This is already a big help for me, but it is also interesting to find out, how Snoop injects itself into another process.
You can accomplish what Snoop does by using the WPF VisualTreeHelper and/or the LogicalTreeHelper. Once you get a hold of any visual element, you can pretty much traverse its entire visual tree to see all the elements it contains. Visual tree helper here
So in your UI test, grab the main window and traverse its visual tree to find any element you want and then perform any validations or operations you want on that element.
Furthermore, you may be able to use System.Diagnostics.Process.MainWindowHandle to get the windows handle from an existing process and then use the window's handle to create a wpf window. Its been a while so I dont remember the specifics without doing more research. The code below may help:
Window window = (Window)System.Windows.Interop.HwndSource.FromHwnd(process.MainWindowHandle).RootVisual;
UPDATE:
Okay, I found the basic code location, that is used by Snoop to provide the injection ability. To my astonishment that code is written C++/CLI. Probably there is a reason for.
And that is the code (I hope that it is okay to post it here):
//-----------------------------------------------------------------------------
//Spying Process functions follow
//-----------------------------------------------------------------------------
void Injector::Launch(System::IntPtr windowHandle, System::String^ assembly, System::String^ className, System::String^ methodName)
{
System::String^ assemblyClassAndMethod = assembly + "$" + className + "$" + methodName;
pin_ptr<const wchar_t> acmLocal = PtrToStringChars(assemblyClassAndMethod);
HINSTANCE hinstDLL;
if (::GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, (LPCTSTR)&MessageHookProc, &hinstDLL))
{
LogMessage("GetModuleHandleEx successful", true);
DWORD processID = 0;
DWORD threadID = ::GetWindowThreadProcessId((HWND)windowHandle.ToPointer(), &processID);
if (processID)
{
LogMessage("Got process id", true);
HANDLE hProcess = ::OpenProcess(PROCESS_ALL_ACCESS, FALSE, processID);
if (hProcess)
{
LogMessage("Got process handle", true);
int buffLen = (assemblyClassAndMethod->Length + 1) * sizeof(wchar_t);
void* acmRemote = ::VirtualAllocEx(hProcess, NULL, buffLen, MEM_COMMIT, PAGE_READWRITE);
if (acmRemote)
{
LogMessage("VirtualAllocEx successful", true);
::WriteProcessMemory(hProcess, acmRemote, acmLocal, buffLen, NULL);
_messageHookHandle = ::SetWindowsHookEx(WH_CALLWNDPROC, &MessageHookProc, hinstDLL, threadID);
if (_messageHookHandle)
{
LogMessage("SetWindowsHookEx successful", true);
::SendMessage((HWND)windowHandle.ToPointer(), WM_GOBABYGO, (WPARAM)acmRemote, 0);
::UnhookWindowsHookEx(_messageHookHandle);
}
::VirtualFreeEx(hProcess, acmRemote, 0, MEM_RELEASE);
}
::CloseHandle(hProcess);
}
}
::FreeLibrary(hinstDLL);
}
}
Snoop doesn't inspect a WPF from the outside. It injects itself into the application and actually adds the magnify or snoop window to it. Thats also why when you exit snoop the inspection windows actually stay open.
So the 'inspection' code simply inspects the window it wants and it can use all avaible WPF functions to do so. Like the VisualTreeHelper and LogicalTreeHelper as mentioned here earlier.
For a small test framework i build i injected code to add a small proxy object so i can control the application easily (press buttons, change values, execute functions on viewmodels etc).
The answer above doesn't work for me. It seems a bit vague. I expanded on accepted answer a little with this code:
var allProcesses = Process.GetProcesses();
var filteredProcess = allProcesses.Where(p => p.ProcessName.Contains(ProcessSearchText)).First();
var windowHandle = filteredProcess.MainWindowHandle;
var hwndSource = HwndSource.FromHwnd(windowHandle);
This answer seems more complete and will work for others if the accepted answer works for anyone. However, this the last line of this code returns null for me.
I want to write an application that will automatically detect and fill the text field in the window shown below:
(assuming the data to be entered is in a file).
The question is how does my application find this text field?
I can do this job if I am able to find the location of the text field on the desktop through program.
Can someone help me understand possible ways for finding this text field?
I am using Windows Form application in C++.
Update:
I played with spy++.
I used spy++, to find the window handle. I did it by putting finder on the window I am interested in. Its giving handle in hex values: 00080086 (actually just for testing purpose I put the finder tool on Visual Studio new project page ). How do I interpret this Hex value into meaningful window name ?
See the below figure.
What is the next step to get to the text field " Enter name" under "name" field.
****Any sample code will be highly appreciated.**
I am open to any solution not necessarily how I am doing this.
One solution is to use the Microsoft UI Automation technology. It's shipped out-of-the-box with Windows since Vista. It's usable from .NET but also from C++ using COM.
Here is a short C++ console application example that displays the class name of the UI Automation Element currently at the middle of the desktop window, each second (you can have it run and see what it displays):
int _tmain(int argc, _TCHAR* argv[])
{
CoInitialize(NULL);
IUIAutomation *pAutomation; // requires Uiautomation.h
HRESULT hr = CoCreateInstance(__uuidof(CUIAutomation), NULL, CLSCTX_INPROC_SERVER, __uuidof(IUIAutomation), (LPVOID *)&pAutomation);
if (SUCCEEDED(hr))
{
RECT rc;
GetWindowRect(GetDesktopWindow(), &rc);
POINT center;
center.x = (rc.right - rc.left) / 2;
center.y = (rc.bottom - rc.top) / 2;
printf("center x:%i y:%i'\n", center.x, center.y);
do
{
IUIAutomationElement *pElement;
hr = pAutomation->ElementFromPoint(center, &pElement);
if (SUCCEEDED(hr))
{
BSTR str;
hr = pElement->get_CurrentClassName(&str);
if (SUCCEEDED(hr))
{
printf("element name:'%S'\n", str);
::SysFreeString(str);
}
pElement->Release();
}
Sleep(1000);
}
while(TRUE);
pAutomation->Release();
}
CoUninitialize();
return 0;
}
From this sample, what you can do is launch the application you want to automate and see if the sample detects it (it should).
You could also use the UISpy tool to display the full tree of what can be automated in your target app. You should see the windows and other elements (text field) of this target app and you should see the element displayed by the console application example.
From the pElement discovered in the sample, you can call FindFirst with the proper condition (class name, name, control type, etc...) to get to the text field. From this text field, you would use one of the UI Automation Patterns that should be available (probably TextPattern or ValuePattern) to get or set the text itself.
The cool thing is you can use the UISpy tool to check all this is possible before actually coding it.
You could enumerate windows and then find it.
For exploring application on your screenshot you could you Spy++ (spyxx.exe) that is distributed with visual studio. In you code, you clould use EnumWindows and EnumChildWindows to enumerates all window or all child windows to find one you need.
Although the answer given by Simon is accepted and is the best one, but still for future visitors I am providing this link which has more description for UI automation of windows applications. .
Also for automating a web application one may want to go to this link
I've read a lot about how to add an icon to an application built with Visual Studio, but I have no idea how to do this with Eclipse Galileo / C / MinGW.
Can anyone write a description, or give me a link ta a description ?
In Windows, the icons as well as some other elements (cursors, bitmaps, ...) have to be specified in a resource file, which once compiled will be linked to the program.
First an example on how to add an icon to a Windows program which will illustrate it's use within Eclipse. Here is a simple program that just creates a window, look at the time we fill the WNDCLASSEX, the icon of the application is referenced there:
resources.h - this file may be used to assign a value to a resource identifier, and so use the value instead:
#define AppIcon 101
The next file is the resources file, you may create it manually or from within Eclipse as well, to create it in Eclipse, right click the directory you want it to be (in this case is src) and select New -> File. There write the name you want and click Finish. To edit it from within Eclipse right click it and select Open with -> Text Editor.
resources.rc - the icon will be specified here:
#include "resources.h"
// The icon path I used will be needed by Eclipse.
// If you want to use back-slashes you have to scape them (\\ instead of \):
AppIcon ICON "../src/icon.ico"
demoicon.c - the file containing the code of the program:
#include <windows.h>
#include "resources.h"
const char *ClassName = "DemoIcon";
// Declaration of the window procedure, to be used in the WNDCLASSEX struct:
LRESULT CALLBACK WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrev, LPSTR lpCmdLine, int nShowCmd) {
WNDCLASSEX wc;
HWND hWnd;
MSG msg;
// Filling the structure:
wc.cbSize = sizeof(WNDCLASSEX);
wc.style = 0;
wc.lpfnWndProc = WindowProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
// Remember this just loads 32x32, use LoadImage() instead for other dimensions (16x16, 48x48, ...):
wc.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(AppIcon));
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH)(COLOR_WINDOW);
wc.lpszMenuName = NULL;
wc.lpszClassName = ClassName;
// Here we'll use LoadImage, as we need a 16x16 mini icon:
wc.hIconSm = LoadImage(hInstance,MAKEINTRESOURCE(AppIcon),IMAGE_ICON,16,16, LR_DEFAULTCOLOR);
// Registering the class:
if(!RegisterClassEx(&wc)) {
MessageBox(NULL,
"Could not register window.",
"Error",
MB_ICONEXCLAMATION | MB_OK);
return -1;
}
// Create the window using the "MainWindow" class:
hWnd = CreateWindowEx(WS_EX_WINDOWEDGE,
ClassName,
"Demo Icon",
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
CW_USEDEFAULT,
200,
150,
NULL,
NULL,
hInstance,
NULL);
// If the window was not created show error and exit:
if(hWnd == NULL) {
MessageBox(NULL,
"Could not create window.",
"Error",
MB_ICONEXCLAMATION | MB_OK);
return -1;
}
// Set the windows show state, to show it:
ShowWindow(hWnd, nShowCmd);
// Draw the window:
UpdateWindow(hWnd);
// Retrieve messages from the message queue:
while(GetMessage(&msg, NULL, 0, 0) > 0) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}
// Implementation of the window procedure, will handle the messages:
LRESULT CALLBACK WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
switch(uMsg) {
case WM_CLOSE:
DestroyWindow(hWnd);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, uMsg, wParam, lParam);
}
return 0;
}
Now, in your Eclipse project source directory make sure you have all the files (in the example the 3 files mentioned before and the icon file).
After that go to Project -> Properties.
There, go to C/C++ Build -> Settings -> Build Steps tab.
There you'll see Pre-build steps -> Command. The command you fill in there will be executed before the compilation starts, so you'll tell it to compile the resource file. As you are using MinGW the resource compiler is windres:
windres ../src/resources.rc -o ../Resources/resources.o
As you can see I'll be placing the compiled resource file in a directory called Resources, you may leave it where you want (and so the name of the file, it doesn't have to be named resources.rc).
Now go to the Tool Settings tab.
There, go to MinGW C Linker -> Miscellaneous, and in other objects add the object file created before, in this case you should add:
Resources/resources.o
As this is a Windows app, add the option -mwindows to the linker flags at the top of the same tab.
Done, when building your project Eclipse will compile the resource file first and then link the generated object as any other object file of your project.
I hope it's clear enough to read through this.
Eclipse isn't set to look at resource files. BUG. So they also have steps to add it to processing. Here are the steps for June. [http://wiki.eclipse.org/CDT/User/FAQ#How_to_handle_Resource-Script-Files_.27.2A.rc.27_with_CDT.3F][1]
How to handle Resource-Script-Files '*.rc' with CDT?
Currently handling of windres.exe with CDT is not possible. You can not add the .rc file to the project to be compiled and linked with automatically. This is already raised as a bug in bugzilla.
One way is to create a Pre-Build Step. Under menue
Project | Properties | C/C++-Build | Settings | Build Steps | Pre-Build Steps
fill in the command-line:
windres --use-temp-file -i..\MyProject.rc -o..\MyProject_rc\MyProject_rc.o
Make the object known to the linker. Under menue
Project | Properties | C/C++-Build | Settings
Tool Settings | MinGW C++ Linker | Miscellaneous | Other Objects
click the icon 'Add', fill in the line:
"C:\MyWorkspace\MyProject\MyProject_rc\MyProject_rc.o"
'MyWorkspace' and 'MyProject' replace with whatever is fitting for your purpose.
You have to add the folder .\MyProject_rc before you build.
The path to windres.exe must be known to eclipse.
The way I did it was by creating a file
icon.rc
#define AppIcon 101
AppIcon ICON "../icon.ico"
Then invoke windres via command prompt with
windres my.rc -O coff -o my.res
It'll compile several files for you -- keep the one called icon.res and rename it as libicon.a. Finally include it in your program by adding it as a library under
Project -> Properties -> Build -> Settings -> C++ Linker -> Libraries
(make sure you tell Eclipse where to find the file using the library paths section underneath).
Hope this helps!
I zip up all of the icons I want to use within the project first. Then
Rename the .zip to a .jar
Create a resource folder if you havent got one already (I use "lib")
Then place the jar file inside the resource folder.
Then one simple addition to the project properties:
by right clicking and Configure "Java Build Path" - select the Libraries tab. Click on the Add JARs button and add the icons.jar to the libraries - then save.
Now its easy to allocate the desired image icon inside the Window Builder editor for example as the jar containing your icons appears within the Image Selection mode chooser within the Classpath resource list. Everything works as it should and compiles fine.