Repository: jobeid/TrayPwrD3 Branch: master Commit: 277a329c8640 Files: 22 Total size: 118.2 KB Directory structure: gitextract_f_fcv1s_/ ├── LICENSE ├── README.md └── src/ ├── AboutDlg.cpp ├── AboutDlg.h ├── D3dx12jo.cpp ├── D3dx12jo.h ├── LICENSE.txt ├── Mainfrm.cpp ├── TrayIcon.CPP ├── TrayPwr.cpp ├── TrayPwr.h ├── TrayPwr.rc ├── TrayPwr.sln ├── TrayPwr.vcxproj ├── TrayPwr.vcxproj.user ├── d3dx12.h ├── mainfrm.h ├── res/ │ └── APP.RC2 ├── resource.h ├── stdafx.cpp ├── stdafx.h └── trayicon.h ================================================ FILE CONTENTS ================================================ ================================================ FILE: LICENSE ================================================ MIT License Copyright© 2017 J.S. Obeid Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files(the \Software\), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and / or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED \AS IS\, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ================================================ FILE: README.md ================================================ # TrayPwrD3 **Keeps dGPU on but idle** until needed. This addresses the Windows 10 (64bit) stutter/mouse freeze on dual GPU laptops (intel or AMD CPU with built in GPU in combination with NVIDIA). TrayPwrD3 runs in the background and stays in a tray icon. ![Tray icon](screenshots/traypwr_icon1.png?raw=true "Tray icon") **Other functionality**: single click turns monitor off to save power until you wake it up by moving the mouse or using the keyboard; provides several menu options on right click; more details in Help menu. This is to address the [Windows 10 and Optimus problem of stutters and mouse hangs](https://forums.geforce.com/default/topic/860554/geforce-mobile-gpus/windows-10-and-optimus/15/). For more about this issue see description on answers.microsoft [Intel + NVIDIA Laptop Freeze Problem](https://answers.microsoft.com/en-us/windows/forum/windows_10-hardware/mobile-gtx-1060-freeze-problem/93e7004a-62b1-4211-8e37-4c136608865e). Note: it is not for stutters in games. It only addresses the desktop stutters in Windows 10 (right click -> display settings, battery icon, chrome and firefox tabs, PowerPoint slideshow etc). If you don't have any of these, then you don't need it. **Windows 10 May 2020 Update:** With this latest update Microsoft fixed the latency issue. However, you will need NVIDIA driver version 451.48 or later. For more information see this Windows Latest post: [Nvidia GeForce 451.48 adds Windows 10 GPU scheduling feature](https://www.windowslatest.com/2020/06/24/nvidia-geforce-451-48-windows-10-hardware-accelerated-gpu-scheduling/). **Update 7/14/2020:** Still noticing some brief hanging during some activities with explorer. So latency issue not totally fixed. **Update 11/12/2020:** Still noticing some major hanging during some activities with explorer and when running certain apps e.g. Media Player Classic on AMD Ryzen systems. So NVIDIA GPU activation latency remains a problem. The updated version of TrayPwrD3 (v2020-11) now supports AMD Ryzen systems and prevents the GPU stutter or latency on both Intel and AMD Ryzen systems. **Update 12/25/2025:** Starting the app now checks if there is a running instance and gives the option to kill it. # Installation Simply download the latest version of the [executable](https://github.com/jobeid/TrayPwrD3/tree/master/executable), uncompress it in any folder and run it. Notes: - The executable was compliled for 64bit windows. - Direct3D version 12 is required. - If you don't already have [Visual C++ Redistributable for Visual Studio](https://support.microsoft.com/en-us/help/2977003/the-latest-supported-visual-c-downloads) installed, then you could download the 64bit version [directly from Microsoft](https://aka.ms/vs/16/release/vc_redist.x64.exe) and install it. - Optional: If you would like to start TrayPwrD3 when windows starts, you can place a shortcut of the executable in the startup folder (located at %USERPROFILE%\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\STARTUP). You can quickly open the startup folder by tapping the Windows key+R to bring up the "Run" dialog, and type `shell:startup` then enter. # Using the App When you start the app it simply runs in the background in a tray icon, keeping the dGPU on but idle. This addresses the well known Windows 10 stutter/mouse freeze on some dual GPU laptops. **To stop the app** simpley right-click the icon and click exit. **There is _no_ need to reboot the system**. # Screenshots Tray icon: ![Tray icon](screenshots/traypwr_icon1.png?raw=true "Tray icon") Right click menu: ![Menu](screenshots/traypwr_rightclick1.png?raw=true "Menu") ================================================ FILE: src/AboutDlg.cpp ================================================ // AboutDlg.cpp : implementation file // #include "stdafx.h" #include "traypwr.h" #include "AboutDlg.h" #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif ///////////////////////////////////////////////////////////////////////////// // CAboutDlg dialog BOOL CAboutDlg::m_bVisible = FALSE; HWND CAboutDlg::m_MyhWnd = NULL; CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD) { m_hChildProcess = NULL; m_dwChildProcessId = 0; //{{AFX_DATA_INIT(CAboutDlg) //}}AFX_DATA_INIT } void CAboutDlg::DoDataExchange(CDataExchange* pDX) { CDialog::DoDataExchange(pDX); //{{AFX_DATA_MAP(CAboutDlg) //}}AFX_DATA_MAP } BEGIN_MESSAGE_MAP(CAboutDlg, CDialog) //{{AFX_MSG_MAP(CAboutDlg) ON_WM_DESTROY() ON_WM_SHOWWINDOW() ON_BN_CLICKED(IDSYSINFO, OnSysinfo) //}}AFX_MSG_MAP END_MESSAGE_MAP() BOOL CAboutDlg::OnInitDialog() { const char *mylic = "MIT License\r\n\r\n" "Copyright 2020 J.S. Obeid\r\n\r\n" "Permission is hereby granted, free of charge, to any person obtaining a copy\r\n" "of this software and associated documentation files(the \"Software\"), to deal\r\n" "in the Software without restriction, including without limitation the rights\r\n" "to use, copy, modify, merge, publish, distribute, sublicense, and / or sell\r\n" "copies of the Software, and to permit persons to whom the Software is\r\n" "furnished to do so, subject to the following conditions : \r\n\r\n" "The above copyright notice and this permission notice shall be included in\r\n" "all copies or substantial portions of the Software.\r\n\r\n" "THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\r\n" "EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES\r\n" "OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND \r\n" "NONINFRINGEMENT.IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\r\n" "HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,\r\n" "WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r\n" "OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\r\n" "DEALINGS IN THE SOFTWARE."; CDialog::OnInitDialog(); GetDlgItem(IDC_EDITLIC)->SetWindowTextA(mylic); return TRUE; // return TRUE unless you set the focus to a control // EXCEPTION: OCX Property Pages should return FALSE } void CAboutDlg::OnSize(UINT nType, int cx, int cy) { CDialog::OnSize(nType, cx, cy); } void CAboutDlg::OnDestroy() { CDialog::OnDestroy(); m_MyhWnd=NULL; //CSystemTray::MinimiseToTray(this); m_bVisible = FALSE; } void CAboutDlg::OnShowWindow(BOOL bShow, UINT nStatus) { CDialog::OnShowWindow(bShow, nStatus); m_MyhWnd=m_hWnd; //if (bShow) CSystemTray::MaximiseFromTray(this); } INT_PTR CAboutDlg::DoModal() { if (m_bVisible) { BringToTop(); return IDCANCEL; } m_bVisible = TRUE; return CDialog::DoModal(); } ///////////////////////////////////////////////////////////////////////////// // CAboutDlg message handlers void CAboutDlg::OnSysinfo() { StartSysInfo(); } void CAboutDlg::BringToTop() { if (m_MyhWnd!=0) { ::SetWindowPos(m_MyhWnd,HWND_TOP,0,0,0,0,SWP_NOMOVE | SWP_NOSIZE); } } BOOL CAboutDlg::OnCommand(WPARAM wParam, LPARAM lParam) { // TODO: Add your specialized code here and/or call the base class return CDialog::OnCommand(wParam, lParam); } //----------------------------------------------------------- // // StartSysInfo() // Calls MSINFO32.EXE // BOOL CAboutDlg::StartSysInfo() { OnInvokeMSInfo("msinfo32.exe"); return TRUE; } //-----------start external exe functions: void CAboutDlg::OnInvokeMSInfo(LPSTR SomeExeNm) { PROCESS_INFORMATION pi; STARTUPINFO si; ZeroMemory(&si, sizeof(STARTUPINFO)); si.cb = sizeof(STARTUPINFO); if (WaitForSingleObject(m_hChildProcess, 0) != WAIT_TIMEOUT && CreateProcess(NULL, SomeExeNm, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi)) { // Close the old process handle CloseHandle(m_hChildProcess); // Close the thread handle (process handle will be closed in ExitInstance) CloseHandle(pi.hThread); // store child process information m_hChildProcess = pi.hProcess; m_dwChildProcessId = pi.dwProcessId; } else { // ActivateChildProcess() activates all top-level windows whose PID matches m_dwChildProcessId. EnumWindows((WNDENUMPROC)CAboutDlg::ActivateChildProcess, (LPARAM)m_dwChildProcessId); } WaitForInputIdle(m_hChildProcess, 1000); } BOOL CALLBACK CAboutDlg::CloseChildProcess(HWND hWnd, LPARAM lParam) { DWORD dwID; GetWindowThreadProcessId(hWnd, &dwID); if (dwID == (DWORD)lParam) { ::PostMessage(hWnd, WM_CLOSE, 0, 0); } return TRUE; } BOOL CALLBACK CAboutDlg::ActivateChildProcess(HWND hWnd, LPARAM lParam) { DWORD dwID; GetWindowThreadProcessId(hWnd, &dwID); if (dwID == (DWORD)lParam) { // Note: This block is adapted from CFrameWnd::ActivateFrame // and from CFrameWnd::BringToTop. int nCmdShow = -1; HWND hWndLastPop; // translate default nCmdShow (-1) if (nCmdShow == -1) { if (::IsIconic(hWnd)) nCmdShow = SW_RESTORE; } ASSERT(nCmdShow != SW_HIDE && nCmdShow != SW_MINIMIZE && nCmdShow != SW_SHOWMINNOACTIVE && nCmdShow != SW_SHOWNA && nCmdShow != SW_SHOWNOACTIVATE); // bring to top before showing // if no last active popup, it will return hWnd hWndLastPop = ::GetLastActivePopup(hWnd); ::BringWindowToTop(hWndLastPop); if (nCmdShow != -1) { // show the window as specified ::ShowWindow(hWnd, nCmdShow); // and finally, bring to top after showing // if no last active popup, it will return hWnd hWndLastPop = ::GetLastActivePopup(hWnd); ::BringWindowToTop(hWndLastPop); } ::PostMessage(hWnd, WM_SETFOCUS, 0, 0); } return TRUE; } ================================================ FILE: src/AboutDlg.h ================================================ // AboutDlg.h : header file // ///////////////////////////////////////////////////////////////////////////// // CAboutDlg dialog class CAboutDlg : public CDialog { public: CAboutDlg(); void BringToTop(); // Dialog Data //{{AFX_DATA(CAboutDlg) enum { IDD = IDD_ABOUTBOX }; //}}AFX_DATA // ClassWizard generated virtual function overrides //{{AFX_VIRTUAL(CAboutDlg) public: virtual INT_PTR DoModal(); protected: virtual void DoDataExchange(CDataExchange* pDX); virtual BOOL OnCommand(WPARAM wParam, LPARAM lParam); //}}AFX_VIRTUAL // Implementation protected: static BOOL m_bVisible; static HWND m_MyhWnd; //stuff for calling external exe's: HANDLE m_hChildProcess; DWORD m_dwChildProcessId; void OnInvokeMSInfo(LPSTR SomeExeNm); static BOOL CALLBACK CloseChildProcess(HWND hWnd, LPARAM lParam); static BOOL CALLBACK ActivateChildProcess(HWND hWnd, LPARAM lParam); BOOL StartSysInfo(); //{{AFX_MSG(CAboutDlg) virtual BOOL OnInitDialog(); afx_msg void OnDestroy(); afx_msg void OnSize(UINT nType, int cx, int cy); afx_msg void OnShowWindow(BOOL bShow, UINT nStatus); afx_msg void OnSysinfo(); //}}AFX_MSG DECLARE_MESSAGE_MAP() }; ================================================ FILE: src/D3dx12jo.cpp ================================================ #include "stdafx.h" #include "D3dx12jo.h" using namespace DirectX; // we will be using the directxmath library D3dx12jo::D3dx12jo() { hwnd_jo = NULL; FullScreen_jo = false; Running = true; } bool D3dx12jo::InitD3D(HWND hwnd_tmp) { HRESULT hr; // -- Create the Device -- // IDXGIFactory4* dxgiFactory; hwnd_jo = hwnd_tmp; hr = CreateDXGIFactory1(IID_PPV_ARGS(&dxgiFactory)); if (FAILED(hr)) { return false; } IDXGIAdapter1* adapter; // adapters are the graphics card (this includes the embedded graphics on the motherboard) int adapterIndex = 0; // we'll start looking for directx 12 compatible graphics devices starting at index 0 bool adapterFound = false; // set this to true when a good one was found // find first hardware gpu that supports d3d 12 //while (dxgiFactory->EnumAdapters1(adapterIndex, &adapter) != DXGI_ERROR_NOT_FOUND) while (adapterIndex<3) { DXGI_ADAPTER_DESC1 desc; if (dxgiFactory->EnumAdapters1(adapterIndex, &adapter) == DXGI_ERROR_NOT_FOUND) { break; } adapter->GetDesc1(&desc); if (desc.Flags & DXGI_ADAPTER_FLAG_SOFTWARE) { // we dont want a software device adapterIndex++; continue; } if (desc.VendorId == 32902) { // we dont want INTEL device (id=0x8086) look up vendor id in device manager adapterIndex++; continue; } if (desc.VendorId == 4098) { // we dont want AMD device (id=0x1002) look up vendor id in device manager adapterIndex++; continue; } // we want a device that is compatible with direct3d 12 (feature level 11 or higher) hr = D3D12CreateDevice(adapter, D3D_FEATURE_LEVEL_11_0, _uuidof(ID3D12Device), nullptr); if (SUCCEEDED(hr)) { adapterFound = true; break; } adapterIndex++; } if (!adapterFound) { return false; } // Create the device hr = D3D12CreateDevice( adapter, D3D_FEATURE_LEVEL_11_0, IID_PPV_ARGS(&device) ); if (FAILED(hr)) { return false; } // -- Create a direct command queue -- // D3D12_COMMAND_QUEUE_DESC cqDesc = {}; cqDesc.Flags = D3D12_COMMAND_QUEUE_FLAG_NONE; cqDesc.Type = D3D12_COMMAND_LIST_TYPE_DIRECT; // direct means the gpu can directly execute this command queue hr = device->CreateCommandQueue(&cqDesc, IID_PPV_ARGS(&commandQueue)); // create the command queue if (FAILED(hr)) { return false; } // -- Create the Swap Chain (double/tripple buffering) -- // DXGI_MODE_DESC backBufferDesc = {}; // this is to describe our display mode backBufferDesc.Width = 300; //Width; // buffer width backBufferDesc.Height = 240; //Height; // buffer height backBufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; // format of the buffer (rgba 32 bits, 8 bits for each chanel) // describe our multi-sampling. We are not multi-sampling, so we set the count to 1 (we need at least one sample of course) DXGI_SAMPLE_DESC sampleDesc = {}; sampleDesc.Count = 1; // multisample count (no multisampling, so we just put 1, since we still need 1 sample) // Describe and create the swap chain. DXGI_SWAP_CHAIN_DESC swapChainDesc = {}; swapChainDesc.BufferCount = FRAME_BUFFER_COUNT_X; // number of buffers we have swapChainDesc.BufferDesc = backBufferDesc; // our back buffer description swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; // this says the pipeline will render to this swap chain swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD; // dxgi will discard the buffer (data) after we call present swapChainDesc.OutputWindow = hwnd_jo; // handle to our window swapChainDesc.SampleDesc = sampleDesc; // our multi-sampling description swapChainDesc.Windowed = !FullScreen_jo; // set to true, then if in fullscreen must call SetFullScreenState with true for full screen to get uncapped fps IDXGISwapChain* tempSwapChain; dxgiFactory->CreateSwapChain( commandQueue, // the queue will be flushed once the swap chain is created &swapChainDesc, // give it the swap chain description we created above &tempSwapChain // store the created swap chain in a temp IDXGISwapChain interface ); swapChain = static_cast(tempSwapChain); frameIndex = swapChain->GetCurrentBackBufferIndex(); // -- Create the Back Buffers (render target views) Descriptor Heap -- // // describe an rtv descriptor heap and create D3D12_DESCRIPTOR_HEAP_DESC rtvHeapDesc = {}; rtvHeapDesc.NumDescriptors = FRAME_BUFFER_COUNT_X; // number of descriptors for this heap. rtvHeapDesc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_RTV; // this heap is a render target view heap // This heap will not be directly referenced by the shaders (not shader visible), as this will store the output from the pipeline // otherwise we would set the heap's flag to D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE rtvHeapDesc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_NONE; hr = device->CreateDescriptorHeap(&rtvHeapDesc, IID_PPV_ARGS(&rtvDescriptorHeap)); if (FAILED(hr)) { return false; } // get the size of a descriptor in this heap (this is a rtv heap, so only rtv descriptors should be stored in it. // descriptor sizes may vary from device to device, which is why there is no set size and we must ask the // device to give us the size. we will use this size to increment a descriptor handle offset rtvDescriptorSize = device->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_RTV); // get a handle to the first descriptor in the descriptor heap. a handle is basically a pointer, // but we cannot literally use it like a c++ pointer. CD3DX12_CPU_DESCRIPTOR_HANDLE rtvHandle(rtvDescriptorHeap->GetCPUDescriptorHandleForHeapStart()); // Create a RTV for each buffer (double buffering is two buffers, tripple buffering is 3). for (int i = 0; i < FRAME_BUFFER_COUNT_X; i++) { // first we get the n'th buffer in the swap chain and store it in the n'th // position of our ID3D12Resource array hr = swapChain->GetBuffer(i, IID_PPV_ARGS(&renderTargets[i])); if (FAILED(hr)) { return false; } // the we "create" a render target view which binds the swap chain buffer (ID3D12Resource[n]) to the rtv handle device->CreateRenderTargetView(renderTargets[i], nullptr, rtvHandle); // we increment the rtv handle by the rtv descriptor size we got above rtvHandle.Offset(1, rtvDescriptorSize); } // -- Create the Command Allocators -- // for (int i = 0; i < FRAME_BUFFER_COUNT_X; i++) { hr = device->CreateCommandAllocator(D3D12_COMMAND_LIST_TYPE_DIRECT, IID_PPV_ARGS(&commandAllocator[i])); if (FAILED(hr)) { return false; } } // -- Create a Command List -- // // create the command list with the first allocator hr = device->CreateCommandList(0, D3D12_COMMAND_LIST_TYPE_DIRECT, commandAllocator[0], NULL, IID_PPV_ARGS(&commandList)); if (FAILED(hr)) { return false; } // command lists are created in the recording state. our main loop will set it up for recording again so close it now commandList->Close(); // -- Create a Fence & Fence Event -- // // create the fences for (int i = 0; i < FRAME_BUFFER_COUNT_X; i++) { hr = device->CreateFence(0, D3D12_FENCE_FLAG_NONE, IID_PPV_ARGS(&fence[i])); if (FAILED(hr)) { return false; } fenceValue[i] = 0; // set the initial fence value to 0 } // create a handle to a fence event fenceEvent = CreateEvent(nullptr, FALSE, FALSE, nullptr); if (fenceEvent == nullptr) { return false; } return true; } void D3dx12jo::UpdatePipeline() { HRESULT hr; // We have to wait for the gpu to finish with the command allocator before we reset it WaitForPreviousFrame(); // we can only reset an allocator once the gpu is done with it // resetting an allocator frees the memory that the command list was stored in hr = commandAllocator[frameIndex]->Reset(); if (FAILED(hr)) { Running = false; } // reset the command list. by resetting the command list we are putting it into // a recording state so we can start recording commands into the command allocator. // the command allocator that we reference here may have multiple command lists // associated with it, but only one can be recording at any time. Make sure // that any other command lists associated to this command allocator are in // the closed state (not recording). // Here you will pass an initial pipeline state object as the second parameter, // but in this tutorial we are only clearing the rtv, and do not actually need // anything but an initial default pipeline, which is what we get by setting // the second parameter to NULL hr = commandList->Reset(commandAllocator[frameIndex], NULL); if (FAILED(hr)) { Running = false; } // here we start recording commands into the commandList (which all the commands will be stored in the commandAllocator) // transition the "frameIndex" render target from the present state to the render target state so the command list draws to it starting from here commandList->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(renderTargets[frameIndex], D3D12_RESOURCE_STATE_PRESENT, D3D12_RESOURCE_STATE_RENDER_TARGET)); // here we again get the handle to our current render target view so we can set it as the render target in the output merger stage of the pipeline CD3DX12_CPU_DESCRIPTOR_HANDLE rtvHandle(rtvDescriptorHeap->GetCPUDescriptorHandleForHeapStart(), frameIndex, rtvDescriptorSize); // set the render target for the output merger stage (the output of the pipeline) commandList->OMSetRenderTargets(1, &rtvHandle, FALSE, nullptr); // Clear the render target by using the ClearRenderTargetView command const float clearColor[] = { 0.0f, 0.2f, 0.4f, 1.0f }; //DARK BLUE commandList->ClearRenderTargetView(rtvHandle, clearColor, 0, nullptr); // transition the "frameIndex" render target from the render target state to the present state. If the debug layer is enabled, you will receive a // warning if present is called on the render target when it's not in the present state commandList->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(renderTargets[frameIndex], D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_PRESENT)); hr = commandList->Close(); if (FAILED(hr)) { Running = false; } } void D3dx12jo::Render() { HRESULT hr; UpdatePipeline(); // update the pipeline by sending commands to the commandqueue // create an array of command lists (only one command list here) ID3D12CommandList* ppCommandLists[] = { commandList }; // execute the array of command lists commandQueue->ExecuteCommandLists(_countof(ppCommandLists), ppCommandLists); // this command goes in at the end of our command queue. we will know when our command queue // has finished because the fence value will be set to "fenceValue" from the GPU since the command // queue is being executed on the GPU hr = commandQueue->Signal(fence[frameIndex], fenceValue[frameIndex]); if (FAILED(hr)) { Running = false; } // present the current backbuffer hr = swapChain->Present(0, 0); if (FAILED(hr)) { Running = false; } } void D3dx12jo::Cleanup() { // wait for the gpu to finish all frames for (int i = 0; i < FRAME_BUFFER_COUNT_X; ++i) { frameIndex = i; WaitForPreviousFrame(); } // get swapchain out of full screen before exiting BOOL fs = false; if (swapChain->GetFullscreenState(&fs, NULL)) swapChain->SetFullscreenState(false, NULL); SAFE_RELEASE(device); SAFE_RELEASE(swapChain); SAFE_RELEASE(commandQueue); SAFE_RELEASE(rtvDescriptorHeap); SAFE_RELEASE(commandList); for (int i = 0; i < FRAME_BUFFER_COUNT_X; ++i) { SAFE_RELEASE(renderTargets[i]); SAFE_RELEASE(commandAllocator[i]); SAFE_RELEASE(fence[i]); }; } void D3dx12jo::WaitForPreviousFrame() { HRESULT hr; // if the current fence value is still less than "fenceValue", then we know the GPU has not finished executing // the command queue since it has not reached the "commandQueue->Signal(fence, fenceValue)" command if (fence[frameIndex]->GetCompletedValue() < fenceValue[frameIndex]) { // we have the fence create an event which is signaled once the fence's current value is "fenceValue" hr = fence[frameIndex]->SetEventOnCompletion(fenceValue[frameIndex], fenceEvent); if (FAILED(hr)) { Running = false; } // We will wait until the fence has triggered the event that it's current value has reached "fenceValue". once it's value // has reached "fenceValue", we know the command queue has finished executing WaitForSingleObject(fenceEvent, INFINITE); } // increment fenceValue for next frame fenceValue[frameIndex]++; // swap the current rtv buffer index so we draw on the correct buffer frameIndex = swapChain->GetCurrentBackBufferIndex(); } void D3dx12jo::CloseFenceHandle() { WaitForPreviousFrame(); CloseHandle(fenceEvent); } ================================================ FILE: src/D3dx12jo.h ================================================ #pragma once #include #include #include #include #include "d3dx12.h" // this will only call release if an object exists (prevents exceptions calling release on non existant objects) #define SAFE_RELEASE(p) { if ( (p) ) { (p)->Release(); (p) = 0; } } #define FRAME_BUFFER_COUNT_X 2 // number of buffers we want, 2 for double buffering, 3 for tripple buffering class D3dx12jo { public: D3dx12jo(); // function declarations bool InitD3D(HWND hwnd); // initializes direct3d 12 void Render(); // execute the command list void Cleanup(); // release com ojects and clean up memory void CloseFenceHandle(); //CloseHandle(fenceEvent); protected: void UpdatePipeline(); // update the direct3d pipeline (update command lists) void WaitForPreviousFrame(); // wait until gpu is finished with command list // Handle to the window HWND hwnd_jo; // is window full screen? bool FullScreen_jo; // we will exit the program when this becomes false bool Running; // direct3d stuff ID3D12Device* device; // direct3d device IDXGISwapChain3* swapChain; // swapchain used to switch between render targets ID3D12CommandQueue* commandQueue; // container for command lists ID3D12DescriptorHeap* rtvDescriptorHeap; // a descriptor heap to hold resources like the render targets ID3D12Resource* renderTargets[FRAME_BUFFER_COUNT_X]; // number of render targets equal to buffer count ID3D12CommandAllocator* commandAllocator[FRAME_BUFFER_COUNT_X]; // we want enough allocators for each buffer * number of threads (we only have one thread) ID3D12GraphicsCommandList* commandList; // a command list we can record commands into, then execute them to render the frame ID3D12Fence* fence[FRAME_BUFFER_COUNT_X]; // an object that is locked while our command list is being executed by the gpu. We need as many //as we have allocators (more if we want to know when the gpu is finished with an asset) HANDLE fenceEvent; // a handle to an event when our fence is unlocked by the gpu UINT64 fenceValue[FRAME_BUFFER_COUNT_X]; // this value is incremented each frame. each fence will have its own value int frameIndex; // current rtv we are on int rtvDescriptorSize; // size of the rtv descriptor on the device (all front and back buffers will be the same size) }; ================================================ FILE: src/LICENSE.txt ================================================ MIT License Copyright 2020 J.S. Obeid Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files(the \Software\), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and / or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED \AS IS\, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ================================================ FILE: src/Mainfrm.cpp ================================================ //////////////////////////////////////////////////////////////// // Main frame window implementation // #include "stdafx.h" #include "TrayPwr.h" #include "mainfrm.h" #include // Message ID used for tray notifications #define WM_MY_TRAY_NOTIFICATION WM_USER+0 #define EWX_FORCEIFHUNG 0x00000010 IMPLEMENT_DYNAMIC(CMainFrame, CFrameWnd) BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd) //{{AFX_MSG_MAP(CMainFrame) ON_MESSAGE(WM_MY_TRAY_NOTIFICATION, OnTrayNotification) ON_WM_CREATE() ON_WM_CLOSE() ON_COMMAND(ID_APPTP_EXIT, OnAppTpExit) ON_COMMAND(ID_TPLOGOFF, OnTpLogOff) ON_COMMAND(ID_TPSHUTDOWN, OnTpShutDown) ON_COMMAND(ID_TPRESTART, OnTpRestart) ON_COMMAND(ID_TPSTANDBY, OnTpStandBy) ON_WM_TIMER() ON_COMMAND(ID_TPSCREENSAVE, OnTpScreenSave) ON_WM_ENDSESSION() //}}AFX_MSG_MAP END_MESSAGE_MAP() static UINT BASED_CODE indicators[] = { ID_SEPARATOR, // status line indicator }; CMainFrame::CMainFrame() : m_trayIcon(IDR_TRAYICON) { m_bShutdown = FALSE; m_DblClicked = FALSE; m_BtnClicked = 0; m_nTicks = 0; m_nTimer = 0; } CMainFrame::~CMainFrame() { } int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct) { if (CFrameWnd::OnCreate(lpCreateStruct) == -1) return -1; if (!m_wndStatusBar.Create(this) || !m_wndStatusBar.SetIndicators(indicators, sizeof(indicators)/sizeof(UINT))) return -1; // fail to create //assign global hwnd for d3dx12 //JJJ SET hwnd_jo IN DXjo class = m_hWnd; D3dx12jo* pD3jo = new D3dx12jo(); m_pD3jo = pD3jo; if (!m_pD3jo->InitD3D(m_hWnd)) { //MessageBox(0, L"Failed to initialize direct3d 12", L"Error", MB_OK); m_pD3jo->Cleanup(); return -1; } // Set up tray icon m_trayIcon.SetNotificationWnd(this, WM_MY_TRAY_NOTIFICATION); m_iWhichIcon = 1; m_trayIcon.SetIcon(IDI_MYICON); // start timer for dx rendering and managing messages OnStartTimer(); return 0; } ////////////////// // Close window. Unless we are shutting down, just hide it. // void CMainFrame::OnClose() { if (m_bShutdown) CFrameWnd::OnClose(); else ShowWindow(SW_HIDE); } ////////////////// // Handle notification from tray icon: display a message. // LRESULT CMainFrame::OnTrayNotification(WPARAM uID, LPARAM lEvent) { switch (lEvent) { case WM_LBUTTONUP: //if one click then turn monitor off: m_BtnClicked=WM_LBUTTONUP; ResetTimerTicks(); break; case WM_LBUTTONDBLCLK: if (m_nTimer!=0) { m_DblClicked=TRUE; m_BtnClicked = 0; if (IsShiftKeyDown()) { OnTpStandBy(); }else{ //OnTpShutDown(); } } break; case WM_RBUTTONUP: m_BtnClicked=WM_RBUTTONUP; ResetTimerTicks(); break; case WM_RBUTTONDBLCLK: if (m_nTimer!=0) { m_DblClicked=TRUE; if (IsShiftKeyDown()) { OnTpLogOff(); }else{ OnTpRestart(); } } break; } // let tray icon do default stuff return 0; } //////////////////////////////////////////////////////////////// // Command handlers below. // void CMainFrame::OnAppTpExit() { m_bShutdown = TRUE; // really exit //clean up dx12: OnStopTimer(); m_pD3jo->CloseFenceHandle(); m_pD3jo->Cleanup(); //close and exit: SendMessage(WM_CLOSE); } void CMainFrame::OnTpLogOff() { TpExitWindows(FALSE,ID_TPLOGOFF); } void CMainFrame::OnTpShutDown() { TpExitWindows(FALSE,ID_TPSHUTDOWN); } void CMainFrame::OnTpRestart() { TpExitWindows(FALSE,ID_TPRESTART); } void CMainFrame::OnTpStandBy() { TpExitWindows(FALSE,ID_TPSTANDBY); } void CMainFrame::OnTpScreenSave() { // TODO: Add your command handler code here m_BtnClicked=WM_TPSCREENSAVER; ResetTimerTicks(); } void CMainFrame::TpExitWindows(BOOL Force,int shtdn) { if(IsWindowsVersionOrGreater(4, 0, 0)) { // Get the access token of the current process. Get it // with the privileges of querying the access token and // adjusting its privileges. HANDLE hToken=0; LUID tLuid; TOKEN_PRIVILEGES tTokenPriv; BOOL bRes=OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES + TOKEN_QUERY, &hToken); if (bRes==0L){ return; //Failed } // Get the locally unique identifier (LUID) which // represents the shutdown privilege. if (LookupPrivilegeValue(0L, "SeShutdownPrivilege", &tLuid)==0L) return; //Failed // Populate the new TOKEN_PRIVILEGES values with the LUID // and allow your current process to shutdown the computer. tTokenPriv.PrivilegeCount=1; tTokenPriv.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; tTokenPriv.Privileges[0].Luid = tLuid; AdjustTokenPrivileges(hToken, FALSE, &tTokenPriv, sizeof(TOKEN_PRIVILEGES), (PTOKEN_PRIVILEGES) NULL, (PDWORD) NULL); } //Now we have the correct privileges, hopefully. //Perform desired windows power-down: UINT FORCE_FLAG=(Force == TRUE ? EWX_FORCEIFHUNG : 0L); switch (shtdn) { case ID_TPLOGOFF:{ ExitWindowsEx(FORCE_FLAG | EWX_LOGOFF, 0L); } break; case ID_TPSHUTDOWN:{ ExitWindowsEx(FORCE_FLAG | EWX_SHUTDOWN | EWX_POWEROFF, 0L); } break; case ID_TPRESTART:{ ExitWindowsEx(FORCE_FLAG | EWX_REBOOT, 0L); } break; case ID_TPSTANDBY:{ SetSystemPowerState(1L, 1L); } break; } } void CMainFrame::OnTimer(UINT_PTR nIDEvent) { // TODO: Add your message handler code here and/or call default if (m_DblClicked==FALSE) { m_nTicks++; if (m_nTicks>2) { //Some useful debugging code: //CString msg; //msg.Format("Hello: m_nTicks=%d", m_nTicks); //MessageBeep(0xFFFFFFFF); // Beep //MessageBox(msg); switch (m_BtnClicked) { case WM_RBUTTONUP: DoMenuDropDown(); m_BtnClicked = 0; break; case WM_LBUTTONUP: //if one click then turn monitor off: if (m_nTicks>18) // but wait longer: 18x50 =900 msec. { if (MonitorOffSupport()==TRUE) { SendMessage(WM_SYSCOMMAND, SC_MONITORPOWER, 2L); } else //no monitor-off support, just kick in screen saver. { SendMessage(WM_SYSCOMMAND, SC_SCREENSAVE, 0L); } m_BtnClicked = 0; } break; case WM_TPSCREENSAVER: if (m_nTicks>10) // but wait longer { SendMessage(WM_SYSCOMMAND, SC_SCREENSAVE, 0L); m_BtnClicked = 0; } break; default: if (m_nTicks > 100) { //TRACE(_T("OnTimer - default, %d ticks.\n", m_nTicks)); m_pD3jo->Render(); ResetTimerTicks(); } break; } } } else //m_DblClicked=TRUE; { m_DblClicked=FALSE; m_BtnClicked = 0; ResetTimerTicks(); } CFrameWnd::OnTimer(nIDEvent); } void CMainFrame::ResetTimerTicks() { m_nTicks = 0; } void CMainFrame::OnStartTimer() { m_nTicks = 0; m_nTimer = SetTimer(1, 50, 0); } void CMainFrame::OnStopTimer() { if (m_nTimer != 0) { KillTimer(m_nTimer); m_nTimer = 0; } } void CMainFrame::DoMenuDropDown() { CMenu menu; if (!menu.LoadMenu(IDR_TRAYICON)) return; CMenu* pSubMenu = menu.GetSubMenu(0); if (!pSubMenu) return; // Make first menu item the default (bold font) //::SetMenuDefaultItem(pSubMenu->m_hMenu, 0, TRUE); // Display the menu at the current mouse location. There's a "bug" // (Microsoft calls it a feature) in Windows 95 that requires calling // SetForegroundWindow. To find out more, search for Q135788 in MSDN. // CPoint mouse; GetCursorPos(&mouse); ::SetForegroundWindow(m_hWnd); ::TrackPopupMenu(pSubMenu->m_hMenu, 0, mouse.x, mouse.y, 0, m_hWnd, NULL); } BOOL CMainFrame::IsShiftKeyDown() { return ((GetAsyncKeyState(VK_SHIFT) & 0x8000)!=0); } // Function MonitorOffSupport() //This function determines if the operating system supports monitor off //Returns false for NT4, true for Win95,98,2000 BOOL CMainFrame::MonitorOffSupport() { if(IsWindowsVersionOrGreater(4, 0, 0)) { if (IsWindowsVersionOrGreater(5, 0, 0)) { return TRUE; // NT 5 or more } return FALSE; // NT 4 or less } return TRUE; //Win95,98 etc... } void CMainFrame::OnEndSession(BOOL bEnding) { CFrameWnd::OnEndSession(bEnding); // Force app to quit: OnAppTpExit(); } ================================================ FILE: src/TrayIcon.CPP ================================================ //////////////////////////////////////////////////////////////// // CTrayIcon adopted from Microsoft Systems Journal's CTrayIcon by Paul DiLascia. // #include "stdafx.h" #include "trayicon.h" #include // for AfxLoadString IMPLEMENT_DYNAMIC(CTrayIcon, CCmdTarget) CTrayIcon::CTrayIcon(UINT uID) { // Initialize NOTIFYICONDATA memset(&m_nid, 0 , sizeof(m_nid)); m_nid.cbSize = sizeof(m_nid); m_nid.uID = uID; // never changes after construction // Use resource string as tip if there is one AfxLoadString(uID, m_nid.szTip, sizeof(m_nid.szTip)); } CTrayIcon::~CTrayIcon() { SetIcon(0); // remove icon from system tray } ////////////////// // Set notification window. It must created already. // void CTrayIcon::SetNotificationWnd(CWnd* pNotifyWnd, UINT uCbMsg) { // If the following assert fails, you're probably // calling me before you created your window. Oops. ASSERT(pNotifyWnd==NULL || ::IsWindow(pNotifyWnd->GetSafeHwnd())); m_nid.hWnd = pNotifyWnd->GetSafeHwnd(); ASSERT(uCbMsg==0 || uCbMsg>=WM_USER); m_nid.uCallbackMessage = uCbMsg; } ////////////////// // This is the main variant for setting the icon. // Sets both the icon and tooltip from resource ID // To remove the icon, call SetIcon(0) // BOOL CTrayIcon::SetIcon(UINT uID) { HICON hicon=NULL; if (uID) { AfxLoadString(uID, m_nid.szTip, sizeof(m_nid.szTip)); //hicon = AfxGetApp()->LoadIcon(uID); hicon=(HICON) LoadImage(AfxGetInstanceHandle(),MAKEINTRESOURCE(uID),IMAGE_ICON,16,16,LR_DEFAULTCOLOR); } return SetIcon(hicon, NULL); } ////////////////// // Common SetIcon for all overloads. // BOOL CTrayIcon::SetIcon(HICON hicon, LPCSTR lpTip) { UINT msg; m_nid.uFlags = 0; // Set the icon if (hicon) { // Add or replace icon in system tray msg = m_nid.hIcon ? NIM_MODIFY : NIM_ADD; m_nid.hIcon = hicon; //m_nid.uFlags |= NIF_ICON; //NIF_ICON Or NIF_TIP Or NIF_MESSAGE m_nid.uFlags = NIF_ICON; //NIF_ICON Or NIF_TIP Or NIF_MESSAGE } else { // remove icon from tray if (m_nid.hIcon==NULL) return TRUE; // already deleted msg = NIM_DELETE; } // Use the tip, if any if (lpTip) strcpy_s(m_nid.szTip, sizeof(m_nid.szTip), lpTip); if (m_nid.szTip[0]) m_nid.uFlags |= NIF_TIP; // Use callback if any if (m_nid.uCallbackMessage && m_nid.hWnd) m_nid.uFlags |= NIF_MESSAGE; // Do it BOOL bRet = Shell_NotifyIcon(msg, &m_nid); if (msg==NIM_DELETE || !bRet) m_nid.hIcon = NULL; // failed return bRet; } ================================================ FILE: src/TrayPwr.cpp ================================================ //////////////////////////////////////////////////////////////// // TrayPwr Adopted from Microsoft Systems Journal's CTrayIcon by Paul DiLascia. // // All the activity takes place in MainFrm.cpp. #include "stdafx.h" #include "TrayPwr.h" #include "mainfrm.h" #include "AboutDlg.h" #include #include CMyApp theApp; BEGIN_MESSAGE_MAP(CMyApp, CWinApp) //{{AFX_MSG_MAP(CMyApp) ON_COMMAND(ID_APP_ABOUT, OnAppAbout) //}}AFX_MSG_MAP END_MESSAGE_MAP() namespace { // Return PID of first other process that has the same executable name as this process. DWORD FindOtherInstancePid() { DWORD myPid = GetCurrentProcessId(); TCHAR myPath[MAX_PATH] = { 0 }; if (!GetModuleFileName(NULL, myPath, _countof(myPath))) return 0; // Extract executable file name only (e.g. "TrayPwrD3.exe") TCHAR *pName = _tcsrchr(myPath, '\\'); LPCTSTR myExeName = pName ? pName + 1 : myPath; HANDLE hsnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); if (hsnap == INVALID_HANDLE_VALUE) return 0; PROCESSENTRY32 pe = { 0 }; pe.dwSize = sizeof(pe); if (Process32First(hsnap, &pe)) { do { // szExeFile holds the base exe name if (pe.th32ProcessID != myPid && _tcsicmp(pe.szExeFile, myExeName) == 0) { CloseHandle(hsnap); return pe.th32ProcessID; } } while (Process32Next(hsnap, &pe)); } CloseHandle(hsnap); return 0; } // Terminates the process with the given PID. Returns TRUE on success. BOOL TerminateProcessByPid(DWORD pid, DWORD timeoutMs = 5000) { HANDLE hProc = OpenProcess(PROCESS_TERMINATE | SYNCHRONIZE, FALSE, pid); if (!hProc) return FALSE; BOOL ok = TerminateProcess(hProc, 0) != FALSE; if (ok) { WaitForSingleObject(hProc, timeoutMs); } CloseHandle(hProc); return ok; } } CMyApp::CMyApp() { } BOOL CMyApp::InitInstance() { // Check for another running instance of this exe DWORD otherPid = FindOtherInstancePid(); if (otherPid != 0) { CString msg; msg.Format(_T("Another instance of %s is already running (PID %u).\n\n" "Do you want to terminate the running instance and continue?"), AfxGetAppName(), otherPid); int res = AfxMessageBox(msg, MB_YESNO | MB_ICONQUESTION); if (res == IDYES) { if (!TerminateProcessByPid(otherPid)) { AfxMessageBox(_T("Failed to terminate the running instance. Startup will be cancelled."), MB_OK | MB_ICONERROR); return FALSE; } // optionally wait a moment to ensure process is gone Sleep(200); } else { // user chose not to terminate the other instance -> exit return FALSE; } } // Create main frame window (don't use doc/view stuff) m_bAboutDialogActive=FALSE; CMainFrame* pMainFrame = new CMainFrame; if (!pMainFrame->LoadFrame(IDR_MAINFRAME)) return FALSE; m_pMainWnd = pMainFrame; return TRUE; } void CMyApp::OnAppAbout() { CAboutDlg aboutDlg; aboutDlg.DoModal(); } ================================================ FILE: src/TrayPwr.h ================================================ //////////////////////////////////////////////////////////////// // TrayPwr Copyright 1996 Microsoft Systems Journal. // See TrayPwr.CPP for description of program. // #include "resource.h" #include "D3dx12jo.h" class CMyApp : public CWinApp { public: CMyApp(); virtual BOOL InitInstance(); //{{AFX_MSG(CMyApp) afx_msg void OnAppAbout(); //}}AFX_MSG DECLARE_MESSAGE_MAP() protected: private: BOOL m_bAboutDialogActive; }; ================================================ FILE: src/TrayPwr.rc ================================================ // Microsoft Visual C++ generated resource script. // #include "resource.h" #define APSTUDIO_READONLY_SYMBOLS ///////////////////////////////////////////////////////////////////////////// // // Generated from the TEXTINCLUDE 2 resource. // #include "afxres.h" ///////////////////////////////////////////////////////////////////////////// #undef APSTUDIO_READONLY_SYMBOLS ///////////////////////////////////////////////////////////////////////////// // English (United States) resources #if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US #pragma code_page(1252) #ifdef APSTUDIO_INVOKED ///////////////////////////////////////////////////////////////////////////// // // TEXTINCLUDE // 1 TEXTINCLUDE BEGIN "resource.h\0" END 2 TEXTINCLUDE BEGIN "#include ""afxres.h""\r\n" "\0" END 3 TEXTINCLUDE BEGIN "#define _AFX_NO_SPLITTER_RESOURCES\r\n" "#define _AFX_NO_OLE_RESOURCES\r\n" "#define _AFX_NO_TRACKER_RESOURCES\r\n" "#define _AFX_NO_PROPERTY_RESOURCES\r\n" "\r\n" "#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)\r\n" "#ifdef _WIN32\r\n" "LANGUAGE 9, 1\r\n" "#pragma code_page(1252)\r\n" "#endif\r\n" "#include ""res\\app.rc2"" // non-Microsoft Visual C++ edited resources\r\n" "#include ""afxres.rc"" // Standard components\r\n" "#endif\0" END #endif // APSTUDIO_INVOKED ///////////////////////////////////////////////////////////////////////////// // // Icon // // Icon with lowest ID value placed first to ensure application icon // remains consistent on all systems. IDR_MAINFRAME ICON "res\\app.ico" IDI_MYICON ICON "res\\myicon.ico" ///////////////////////////////////////////////////////////////////////////// // // Menu // IDR_MAINFRAME MENU BEGIN POPUP "&File" BEGIN MENUITEM "&About TrayPwr...", ID_APP_ABOUT MENUITEM "E&xit", ID_APP_EXIT END POPUP "&View" BEGIN MENUITEM "&Status Bar", ID_VIEW_STATUS_BAR END END IDR_TRAYICON MENU BEGIN POPUP "&Tray" BEGIN MENUITEM "&Help...", ID_APP_ABOUT MENUITEM "&Log off", ID_TPLOGOFF MENUITEM "Shut &down", ID_TPSHUTDOWN MENUITEM "&Restart", ID_TPRESTART MENUITEM "Stand &by", ID_TPSTANDBY MENUITEM "&Screen Saver", ID_TPSCREENSAVE MENUITEM "E&xit", ID_APPTP_EXIT END END ///////////////////////////////////////////////////////////////////////////// // // Dialog // IDD_ABOUTBOX DIALOGEX 0, 0, 268, 188 STYLE DS_SETFONT | DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU CAPTION "TrayPower D3 Help" FONT 8, "MS Sans Serif", 0, 0, 0x0 BEGIN DEFPUSHBUTTON "&OK",IDOK,206,64,56,15,WS_GROUP LTEXT "TrayPower D3 (Keeps dGPU on/idle)\nVersion 1.7.0.0",IDC_STATIC,36,7,154,17,NOT WS_GROUP LTEXT "Copyright 2020 J. S. Obeid",IDC_STATIC,36,23,167,9,NOT WS_GROUP ICON IDR_MAINFRAME,IDC_STATIC,9,9,20,20,SS_SUNKEN LTEXT "Keeps dGPU idle + sits in tray icon. Options:",IDC_STATIC,6,34,237,9,NOT WS_GROUP LTEXT "Left click: turns monitor off, and saves battery power without powering down. ",IDC_STATIC,6,42,240,9,NOT WS_GROUP PUSHBUTTON "&System Info...",IDSYSINFO,206,6,56,15,WS_GROUP LTEXT "Right click: power-down menu.\nRight double click : restarts computer.\nShift Left double click: goes into Stand by.\nShift Right double click: logs off. ",IDC_STATIC,6,49,141,35,NOT WS_GROUP EDITTEXT IDC_EDITLIC,6,84,256,100,ES_MULTILINE | ES_AUTOHSCROLL | ES_READONLY | WS_VSCROLL | WS_HSCROLL END ///////////////////////////////////////////////////////////////////////////// // // Version // AFX_ID_PREVIEW_ZOOMOUT VERSIONINFO FILEVERSION 1,8,0,0 PRODUCTVERSION 1,8,0,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L #else FILEFLAGS 0x0L #endif FILEOS 0x4L FILETYPE 0x1L FILESUBTYPE 0x0L BEGIN BLOCK "StringFileInfo" BEGIN BLOCK "040904b0" BEGIN VALUE "Comments", "Tray Power D3" VALUE "CompanyName", "J Obeid Software" VALUE "FileDescription", "TrayPwrD3" VALUE "FileVersion", "1.8.0.0" VALUE "InternalName", "TrayPwr" VALUE "LegalCopyright", "Copyright 2025 J. S. Obeid" VALUE "OriginalFilename", "TrayPwr.exe" VALUE "ProductName", "Tray Power D3" VALUE "ProductVersion", "1.8.0.0" END END BLOCK "VarFileInfo" BEGIN VALUE "Translation", 0x409, 1200 END END ///////////////////////////////////////////////////////////////////////////// // // DESIGNINFO // #ifdef APSTUDIO_INVOKED GUIDELINES DESIGNINFO BEGIN IDD_ABOUTBOX, DIALOG BEGIN LEFTMARGIN, 6 RIGHTMARGIN, 262 TOPMARGIN, 6 BOTTOMMARGIN, 184 END END #endif // APSTUDIO_INVOKED ///////////////////////////////////////////////////////////////////////////// // // AFX_DIALOG_LAYOUT // IDD_ABOUTBOX AFX_DIALOG_LAYOUT BEGIN 0 END ///////////////////////////////////////////////////////////////////////////// // // String Table // STRINGTABLE BEGIN IDR_MAINFRAME "Tray Power" END STRINGTABLE BEGIN IDI_MYICON "TrayPwrD3 - monitor off" END STRINGTABLE BEGIN AFX_IDS_APP_TITLE "TrayPwrD3" AFX_IDS_IDLEMESSAGE "Ready" END STRINGTABLE BEGIN ID_APP_ABOUT "Display program information" ID_APP_EXIT "Hide window" END STRINGTABLE BEGIN ID_APPTP_EXIT "Quit Tray Power and remove from system tray" END #endif // English (United States) resources ///////////////////////////////////////////////////////////////////////////// #ifndef APSTUDIO_INVOKED ///////////////////////////////////////////////////////////////////////////// // // Generated from the TEXTINCLUDE 3 resource. // #define _AFX_NO_SPLITTER_RESOURCES #define _AFX_NO_OLE_RESOURCES #define _AFX_NO_TRACKER_RESOURCES #define _AFX_NO_PROPERTY_RESOURCES #if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) #ifdef _WIN32 LANGUAGE 9, 1 #pragma code_page(1252) #endif #include "res\app.rc2" // non-Microsoft Visual C++ edited resources #include "afxres.rc" // Standard components #endif ///////////////////////////////////////////////////////////////////////////// #endif // not APSTUDIO_INVOKED ================================================ FILE: src/TrayPwr.sln ================================================  Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio 14 VisualStudioVersion = 14.0.25420.1 MinimumVisualStudioVersion = 10.0.40219.1 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "TrayPwr", "TrayPwr.vcxproj", "{8B5413C2-0C8A-4E4F-A42E-C3AE5A763DA4}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|x64 = Debug|x64 Debug|x86 = Debug|x86 Release|x64 = Release|x64 Release|x86 = Release|x86 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution {8B5413C2-0C8A-4E4F-A42E-C3AE5A763DA4}.Debug|x64.ActiveCfg = Debug|x64 {8B5413C2-0C8A-4E4F-A42E-C3AE5A763DA4}.Debug|x64.Build.0 = Debug|x64 {8B5413C2-0C8A-4E4F-A42E-C3AE5A763DA4}.Debug|x86.ActiveCfg = Debug|Win32 {8B5413C2-0C8A-4E4F-A42E-C3AE5A763DA4}.Debug|x86.Build.0 = Debug|Win32 {8B5413C2-0C8A-4E4F-A42E-C3AE5A763DA4}.Release|x64.ActiveCfg = Release|x64 {8B5413C2-0C8A-4E4F-A42E-C3AE5A763DA4}.Release|x64.Build.0 = Release|x64 {8B5413C2-0C8A-4E4F-A42E-C3AE5A763DA4}.Release|x86.ActiveCfg = Release|Win32 {8B5413C2-0C8A-4E4F-A42E-C3AE5A763DA4}.Release|x86.Build.0 = Release|Win32 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection EndGlobal ================================================ FILE: src/TrayPwr.vcxproj ================================================  Debug Win32 Debug x64 Release Win32 Release x64 MFCProj {8B5413C2-0C8A-4E4F-A42E-C3AE5A763DA4} 10.0 TrayPwrD3 Application v143 Dynamic MultiByte Application v143 Dynamic MultiByte Application v143 Dynamic MultiByte Application v143 Dynamic true NotSet .\Release\ .\Release\ false false .\Debug\ .\Debug\ true true MultiThreadedDLL Default true true MinSpace true Level3 WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions) .\Release\ true .\Release\TrayPwr.pch Use STDAFX.H .\Release\ .\Release\ true NDEBUG;%(PreprocessorDefinitions) .\Release\TrayPwr.tlb true Win32 0x0409 NDEBUG;%(PreprocessorDefinitions) true .\Release\TrayPwr.bsc true .\Release\TrayPwr.exe oldnames.lib;%(AdditionalDependencies) 10240 Windows MultiThreadedDLL Default true true MinSpace true Level3 true Use stdafx.h true WIN32;NDEBUG;_WINDOWS;NO_WARN_MBCS_MFC_DEPRECATION;%(PreprocessorDefinitions) true NDEBUG;%(PreprocessorDefinitions) .\Release\TrayPwr.tlb true 0x0409 NDEBUG;%(PreprocessorDefinitions) true true d3d12.lib;dxgi.lib;d3dcompiler.lib;%(AdditionalDependencies) 10240 Windows MultiThreadedDebugDLL Default false Disabled true Level3 true EditAndContinue WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions) .\Debug\ true .\Debug\TrayPwr.pch Use STDAFX.H .\Debug\ .\Debug\ true _DEBUG;%(PreprocessorDefinitions) .\Debug\TrayPwr.tlb true Win32 0x0409 _DEBUG;%(PreprocessorDefinitions) true .\Debug\TrayPwr.bsc true true .\Debug\TrayPwr.exe oldnames.lib;%(AdditionalDependencies) 10240 Windows MultiThreadedDebugDLL Default false Disabled true Level3 ProgramDatabase WIN32;NDEBUG;_WINDOWS;NO_WARN_MBCS_MFC_DEPRECATION;%(PreprocessorDefinitions) true Use stdafx.h false true _DEBUG;%(PreprocessorDefinitions) .\Debug\TrayPwr.tlb true 0x0409 _DEBUG;%(PreprocessorDefinitions) true true true d3d12.lib;dxgi.lib;d3dcompiler.lib;%(AdditionalDependencies) 10240 Windows Create Create Use ================================================ FILE: src/TrayPwr.vcxproj.user ================================================  TrayPwr.rc true ================================================ FILE: src/d3dx12.h ================================================ ////////////////////////////////////////////////////////////////////////////// // // Copyright (C) Microsoft Corporation. All Rights Reserved. // // File: d3dx12.h // Content: D3DX12 utility library // ////////////////////////////////////////////////////////////////////////////// #ifndef __D3DX12_H__ #define __D3DX12_H__ #include "d3d12.h" #if defined( __cplusplus ) struct CD3DX12_DEFAULT {}; extern const DECLSPEC_SELECTANY CD3DX12_DEFAULT D3D12_DEFAULT; //------------------------------------------------------------------------------------------------ inline bool operator==(const D3D12_VIEWPORT& l, const D3D12_VIEWPORT& r) { return l.TopLeftX == r.TopLeftX && l.TopLeftY == r.TopLeftY && l.Width == r.Width && l.Height == r.Height && l.MinDepth == r.MinDepth && l.MaxDepth == r.MaxDepth; } //------------------------------------------------------------------------------------------------ inline bool operator!=(const D3D12_VIEWPORT& l, const D3D12_VIEWPORT& r) { return !(l == r); } //------------------------------------------------------------------------------------------------ struct CD3DX12_RECT : public D3D12_RECT { CD3DX12_RECT() {} explicit CD3DX12_RECT(const D3D12_RECT& o) : D3D12_RECT(o) {} explicit CD3DX12_RECT( LONG Left, LONG Top, LONG Right, LONG Bottom) { left = Left; top = Top; right = Right; bottom = Bottom; } ~CD3DX12_RECT() {} operator const D3D12_RECT&() const { return *this; } }; //------------------------------------------------------------------------------------------------ struct CD3DX12_BOX : public D3D12_BOX { CD3DX12_BOX() {} explicit CD3DX12_BOX(const D3D12_BOX& o) : D3D12_BOX(o) {} explicit CD3DX12_BOX( LONG Left, LONG Right) { left = Left; top = 0; front = 0; right = Right; bottom = 1; back = 1; } explicit CD3DX12_BOX( LONG Left, LONG Top, LONG Right, LONG Bottom) { left = Left; top = Top; front = 0; right = Right; bottom = Bottom; back = 1; } explicit CD3DX12_BOX( LONG Left, LONG Top, LONG Front, LONG Right, LONG Bottom, LONG Back) { left = Left; top = Top; front = Front; right = Right; bottom = Bottom; back = Back; } ~CD3DX12_BOX() {} operator const D3D12_BOX&() const { return *this; } }; inline bool operator==(const D3D12_BOX& l, const D3D12_BOX& r) { return l.left == r.left && l.top == r.top && l.front == r.front && l.right == r.right && l.bottom == r.bottom && l.back == r.back; } inline bool operator!=(const D3D12_BOX& l, const D3D12_BOX& r) { return !(l == r); } //------------------------------------------------------------------------------------------------ struct CD3DX12_DEPTH_STENCIL_DESC : public D3D12_DEPTH_STENCIL_DESC { CD3DX12_DEPTH_STENCIL_DESC() {} explicit CD3DX12_DEPTH_STENCIL_DESC(const D3D12_DEPTH_STENCIL_DESC& o) : D3D12_DEPTH_STENCIL_DESC(o) {} explicit CD3DX12_DEPTH_STENCIL_DESC(CD3DX12_DEFAULT) { DepthEnable = TRUE; DepthWriteMask = D3D12_DEPTH_WRITE_MASK_ALL; DepthFunc = D3D12_COMPARISON_FUNC_LESS; StencilEnable = FALSE; StencilReadMask = D3D12_DEFAULT_STENCIL_READ_MASK; StencilWriteMask = D3D12_DEFAULT_STENCIL_WRITE_MASK; const D3D12_DEPTH_STENCILOP_DESC defaultStencilOp = { D3D12_STENCIL_OP_KEEP, D3D12_STENCIL_OP_KEEP, D3D12_STENCIL_OP_KEEP, D3D12_COMPARISON_FUNC_ALWAYS }; FrontFace = defaultStencilOp; BackFace = defaultStencilOp; } explicit CD3DX12_DEPTH_STENCIL_DESC( BOOL depthEnable, D3D12_DEPTH_WRITE_MASK depthWriteMask, D3D12_COMPARISON_FUNC depthFunc, BOOL stencilEnable, UINT8 stencilReadMask, UINT8 stencilWriteMask, D3D12_STENCIL_OP frontStencilFailOp, D3D12_STENCIL_OP frontStencilDepthFailOp, D3D12_STENCIL_OP frontStencilPassOp, D3D12_COMPARISON_FUNC frontStencilFunc, D3D12_STENCIL_OP backStencilFailOp, D3D12_STENCIL_OP backStencilDepthFailOp, D3D12_STENCIL_OP backStencilPassOp, D3D12_COMPARISON_FUNC backStencilFunc) { DepthEnable = depthEnable; DepthWriteMask = depthWriteMask; DepthFunc = depthFunc; StencilEnable = stencilEnable; StencilReadMask = stencilReadMask; StencilWriteMask = stencilWriteMask; FrontFace.StencilFailOp = frontStencilFailOp; FrontFace.StencilDepthFailOp = frontStencilDepthFailOp; FrontFace.StencilPassOp = frontStencilPassOp; FrontFace.StencilFunc = frontStencilFunc; BackFace.StencilFailOp = backStencilFailOp; BackFace.StencilDepthFailOp = backStencilDepthFailOp; BackFace.StencilPassOp = backStencilPassOp; BackFace.StencilFunc = backStencilFunc; } ~CD3DX12_DEPTH_STENCIL_DESC() {} operator const D3D12_DEPTH_STENCIL_DESC&() const { return *this; } }; //------------------------------------------------------------------------------------------------ struct CD3DX12_BLEND_DESC : public D3D12_BLEND_DESC { CD3DX12_BLEND_DESC() {} explicit CD3DX12_BLEND_DESC(const D3D12_BLEND_DESC& o) : D3D12_BLEND_DESC(o) {} explicit CD3DX12_BLEND_DESC(CD3DX12_DEFAULT) { AlphaToCoverageEnable = FALSE; IndependentBlendEnable = FALSE; const D3D12_RENDER_TARGET_BLEND_DESC defaultRenderTargetBlendDesc = { FALSE,FALSE, D3D12_BLEND_ONE, D3D12_BLEND_ZERO, D3D12_BLEND_OP_ADD, D3D12_BLEND_ONE, D3D12_BLEND_ZERO, D3D12_BLEND_OP_ADD, D3D12_LOGIC_OP_NOOP, D3D12_COLOR_WRITE_ENABLE_ALL, }; for (UINT i = 0; i < D3D12_SIMULTANEOUS_RENDER_TARGET_COUNT; ++i) RenderTarget[i] = defaultRenderTargetBlendDesc; } ~CD3DX12_BLEND_DESC() {} operator const D3D12_BLEND_DESC&() const { return *this; } }; //------------------------------------------------------------------------------------------------ struct CD3DX12_RASTERIZER_DESC : public D3D12_RASTERIZER_DESC { CD3DX12_RASTERIZER_DESC() {} explicit CD3DX12_RASTERIZER_DESC(const D3D12_RASTERIZER_DESC& o) : D3D12_RASTERIZER_DESC(o) {} explicit CD3DX12_RASTERIZER_DESC(CD3DX12_DEFAULT) { FillMode = D3D12_FILL_MODE_SOLID; CullMode = D3D12_CULL_MODE_BACK; FrontCounterClockwise = FALSE; DepthBias = D3D12_DEFAULT_DEPTH_BIAS; DepthBiasClamp = D3D12_DEFAULT_DEPTH_BIAS_CLAMP; SlopeScaledDepthBias = D3D12_DEFAULT_SLOPE_SCALED_DEPTH_BIAS; DepthClipEnable = TRUE; MultisampleEnable = FALSE; AntialiasedLineEnable = FALSE; ForcedSampleCount = 0; ConservativeRaster = D3D12_CONSERVATIVE_RASTERIZATION_MODE_OFF; } explicit CD3DX12_RASTERIZER_DESC( D3D12_FILL_MODE fillMode, D3D12_CULL_MODE cullMode, BOOL frontCounterClockwise, INT depthBias, FLOAT depthBiasClamp, FLOAT slopeScaledDepthBias, BOOL depthClipEnable, BOOL multisampleEnable, BOOL antialiasedLineEnable, UINT forcedSampleCount, D3D12_CONSERVATIVE_RASTERIZATION_MODE conservativeRaster) { FillMode = fillMode; CullMode = cullMode; FrontCounterClockwise = frontCounterClockwise; DepthBias = depthBias; DepthBiasClamp = depthBiasClamp; SlopeScaledDepthBias = slopeScaledDepthBias; DepthClipEnable = depthClipEnable; MultisampleEnable = multisampleEnable; AntialiasedLineEnable = antialiasedLineEnable; ForcedSampleCount = forcedSampleCount; ConservativeRaster = conservativeRaster; } ~CD3DX12_RASTERIZER_DESC() {} operator const D3D12_RASTERIZER_DESC&() const { return *this; } }; //------------------------------------------------------------------------------------------------ struct CD3DX12_RESOURCE_ALLOCATION_INFO : public D3D12_RESOURCE_ALLOCATION_INFO { CD3DX12_RESOURCE_ALLOCATION_INFO() {} explicit CD3DX12_RESOURCE_ALLOCATION_INFO(const D3D12_RESOURCE_ALLOCATION_INFO& o) : D3D12_RESOURCE_ALLOCATION_INFO(o) {} CD3DX12_RESOURCE_ALLOCATION_INFO( UINT64 size, UINT64 alignment) { SizeInBytes = size; Alignment = alignment; } operator const D3D12_RESOURCE_ALLOCATION_INFO&() const { return *this; } }; //------------------------------------------------------------------------------------------------ struct CD3DX12_HEAP_PROPERTIES : public D3D12_HEAP_PROPERTIES { CD3DX12_HEAP_PROPERTIES() {} explicit CD3DX12_HEAP_PROPERTIES(const D3D12_HEAP_PROPERTIES &o) : D3D12_HEAP_PROPERTIES(o) {} CD3DX12_HEAP_PROPERTIES( D3D12_CPU_PAGE_PROPERTY cpuPageProperty, D3D12_MEMORY_POOL memoryPoolPreference, UINT creationNodeMask = 1, UINT nodeMask = 1) { Type = D3D12_HEAP_TYPE_CUSTOM; CPUPageProperty = cpuPageProperty; MemoryPoolPreference = memoryPoolPreference; CreationNodeMask = creationNodeMask; VisibleNodeMask = nodeMask; } explicit CD3DX12_HEAP_PROPERTIES( D3D12_HEAP_TYPE type, UINT creationNodeMask = 1, UINT nodeMask = 1) { Type = type; CPUPageProperty = D3D12_CPU_PAGE_PROPERTY_UNKNOWN; MemoryPoolPreference = D3D12_MEMORY_POOL_UNKNOWN; CreationNodeMask = creationNodeMask; VisibleNodeMask = nodeMask; } operator const D3D12_HEAP_PROPERTIES&() const { return *this; } bool IsCPUAccessible() const { return Type == D3D12_HEAP_TYPE_UPLOAD || Type == D3D12_HEAP_TYPE_READBACK || (Type == D3D12_HEAP_TYPE_CUSTOM && (CPUPageProperty == D3D12_CPU_PAGE_PROPERTY_WRITE_COMBINE || CPUPageProperty == D3D12_CPU_PAGE_PROPERTY_WRITE_BACK)); } }; inline bool operator==(const D3D12_HEAP_PROPERTIES& l, const D3D12_HEAP_PROPERTIES& r) { return l.Type == r.Type && l.CPUPageProperty == r.CPUPageProperty && l.MemoryPoolPreference == r.MemoryPoolPreference && l.CreationNodeMask == r.CreationNodeMask && l.VisibleNodeMask == r.VisibleNodeMask; } inline bool operator!=(const D3D12_HEAP_PROPERTIES& l, const D3D12_HEAP_PROPERTIES& r) { return !(l == r); } //------------------------------------------------------------------------------------------------ struct CD3DX12_HEAP_DESC : public D3D12_HEAP_DESC { CD3DX12_HEAP_DESC() {} explicit CD3DX12_HEAP_DESC(const D3D12_HEAP_DESC &o) : D3D12_HEAP_DESC(o) {} CD3DX12_HEAP_DESC( UINT64 size, D3D12_HEAP_PROPERTIES properties, UINT64 alignment = 0, D3D12_HEAP_FLAGS flags = D3D12_HEAP_FLAG_NONE) { SizeInBytes = size; Properties = properties; Alignment = alignment; Flags = flags; } CD3DX12_HEAP_DESC( UINT64 size, D3D12_HEAP_TYPE type, UINT64 alignment = 0, D3D12_HEAP_FLAGS flags = D3D12_HEAP_FLAG_NONE) { SizeInBytes = size; Properties = CD3DX12_HEAP_PROPERTIES(type); Alignment = alignment; Flags = flags; } CD3DX12_HEAP_DESC( UINT64 size, D3D12_CPU_PAGE_PROPERTY cpuPageProperty, D3D12_MEMORY_POOL memoryPoolPreference, UINT64 alignment = 0, D3D12_HEAP_FLAGS flags = D3D12_HEAP_FLAG_NONE) { SizeInBytes = size; Properties = CD3DX12_HEAP_PROPERTIES(cpuPageProperty, memoryPoolPreference); Alignment = alignment; Flags = flags; } CD3DX12_HEAP_DESC( const D3D12_RESOURCE_ALLOCATION_INFO& resAllocInfo, D3D12_HEAP_PROPERTIES properties, D3D12_HEAP_FLAGS flags = D3D12_HEAP_FLAG_NONE) { SizeInBytes = resAllocInfo.SizeInBytes; Properties = properties; Alignment = resAllocInfo.Alignment; Flags = flags; } CD3DX12_HEAP_DESC( const D3D12_RESOURCE_ALLOCATION_INFO& resAllocInfo, D3D12_HEAP_TYPE type, D3D12_HEAP_FLAGS flags = D3D12_HEAP_FLAG_NONE) { SizeInBytes = resAllocInfo.SizeInBytes; Properties = CD3DX12_HEAP_PROPERTIES(type); Alignment = resAllocInfo.Alignment; Flags = flags; } CD3DX12_HEAP_DESC( const D3D12_RESOURCE_ALLOCATION_INFO& resAllocInfo, D3D12_CPU_PAGE_PROPERTY cpuPageProperty, D3D12_MEMORY_POOL memoryPoolPreference, D3D12_HEAP_FLAGS flags = D3D12_HEAP_FLAG_NONE) { SizeInBytes = resAllocInfo.SizeInBytes; Properties = CD3DX12_HEAP_PROPERTIES(cpuPageProperty, memoryPoolPreference); Alignment = resAllocInfo.Alignment; Flags = flags; } operator const D3D12_HEAP_DESC&() const { return *this; } bool IsCPUAccessible() const { return static_cast< const CD3DX12_HEAP_PROPERTIES* >(&Properties)->IsCPUAccessible(); } }; inline bool operator==(const D3D12_HEAP_DESC& l, const D3D12_HEAP_DESC& r) { return l.SizeInBytes == r.SizeInBytes && l.Properties == r.Properties && l.Alignment == r.Alignment && l.Flags == r.Flags; } inline bool operator!=(const D3D12_HEAP_DESC& l, const D3D12_HEAP_DESC& r) { return !(l == r); } //------------------------------------------------------------------------------------------------ struct CD3DX12_CLEAR_VALUE : public D3D12_CLEAR_VALUE { CD3DX12_CLEAR_VALUE() {} explicit CD3DX12_CLEAR_VALUE(const D3D12_CLEAR_VALUE &o) : D3D12_CLEAR_VALUE(o) {} CD3DX12_CLEAR_VALUE( DXGI_FORMAT format, const FLOAT color[4]) { Format = format; memcpy(Color, color, sizeof(Color)); } CD3DX12_CLEAR_VALUE( DXGI_FORMAT format, FLOAT depth, UINT8 stencil) { Format = format; /* Use memcpy to preserve NAN values */ memcpy(&DepthStencil.Depth, &depth, sizeof(depth)); DepthStencil.Stencil = stencil; } operator const D3D12_CLEAR_VALUE&() const { return *this; } }; //------------------------------------------------------------------------------------------------ struct CD3DX12_RANGE : public D3D12_RANGE { CD3DX12_RANGE() {} explicit CD3DX12_RANGE(const D3D12_RANGE &o) : D3D12_RANGE(o) {} CD3DX12_RANGE( SIZE_T begin, SIZE_T end) { Begin = begin; End = end; } operator const D3D12_RANGE&() const { return *this; } }; //------------------------------------------------------------------------------------------------ struct CD3DX12_TILED_RESOURCE_COORDINATE : public D3D12_TILED_RESOURCE_COORDINATE { CD3DX12_TILED_RESOURCE_COORDINATE() {} explicit CD3DX12_TILED_RESOURCE_COORDINATE(const D3D12_TILED_RESOURCE_COORDINATE &o) : D3D12_TILED_RESOURCE_COORDINATE(o) {} CD3DX12_TILED_RESOURCE_COORDINATE( UINT x, UINT y, UINT z, UINT subresource) { X = x; Y = y; Z = z; Subresource = subresource; } operator const D3D12_TILED_RESOURCE_COORDINATE&() const { return *this; } }; //------------------------------------------------------------------------------------------------ struct CD3DX12_TILE_REGION_SIZE : public D3D12_TILE_REGION_SIZE { CD3DX12_TILE_REGION_SIZE() {} explicit CD3DX12_TILE_REGION_SIZE(const D3D12_TILE_REGION_SIZE &o) : D3D12_TILE_REGION_SIZE(o) {} CD3DX12_TILE_REGION_SIZE( UINT numTiles, BOOL useBox, UINT width, UINT16 height, UINT16 depth) { NumTiles = numTiles; UseBox = useBox; Width = width; Height = height; Depth = depth; } operator const D3D12_TILE_REGION_SIZE&() const { return *this; } }; //------------------------------------------------------------------------------------------------ struct CD3DX12_SUBRESOURCE_TILING : public D3D12_SUBRESOURCE_TILING { CD3DX12_SUBRESOURCE_TILING() {} explicit CD3DX12_SUBRESOURCE_TILING(const D3D12_SUBRESOURCE_TILING &o) : D3D12_SUBRESOURCE_TILING(o) {} CD3DX12_SUBRESOURCE_TILING( UINT widthInTiles, UINT16 heightInTiles, UINT16 depthInTiles, UINT startTileIndexInOverallResource) { WidthInTiles = widthInTiles; HeightInTiles = heightInTiles; DepthInTiles = depthInTiles; StartTileIndexInOverallResource = startTileIndexInOverallResource; } operator const D3D12_SUBRESOURCE_TILING&() const { return *this; } }; //------------------------------------------------------------------------------------------------ struct CD3DX12_TILE_SHAPE : public D3D12_TILE_SHAPE { CD3DX12_TILE_SHAPE() {} explicit CD3DX12_TILE_SHAPE(const D3D12_TILE_SHAPE &o) : D3D12_TILE_SHAPE(o) {} CD3DX12_TILE_SHAPE( UINT widthInTexels, UINT heightInTexels, UINT depthInTexels) { WidthInTexels = widthInTexels; HeightInTexels = heightInTexels; DepthInTexels = depthInTexels; } operator const D3D12_TILE_SHAPE&() const { return *this; } }; //------------------------------------------------------------------------------------------------ struct CD3DX12_RESOURCE_BARRIER : public D3D12_RESOURCE_BARRIER { CD3DX12_RESOURCE_BARRIER() {} explicit CD3DX12_RESOURCE_BARRIER(const D3D12_RESOURCE_BARRIER &o) : D3D12_RESOURCE_BARRIER(o) {} static inline CD3DX12_RESOURCE_BARRIER Transition( _In_ ID3D12Resource* pResource, D3D12_RESOURCE_STATES stateBefore, D3D12_RESOURCE_STATES stateAfter, UINT subresource = D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES, D3D12_RESOURCE_BARRIER_FLAGS flags = D3D12_RESOURCE_BARRIER_FLAG_NONE) { CD3DX12_RESOURCE_BARRIER result; ZeroMemory(&result, sizeof(result)); D3D12_RESOURCE_BARRIER &barrier = result; result.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION; result.Flags = flags; barrier.Transition.pResource = pResource; barrier.Transition.StateBefore = stateBefore; barrier.Transition.StateAfter = stateAfter; barrier.Transition.Subresource = subresource; return result; } static inline CD3DX12_RESOURCE_BARRIER Aliasing( _In_ ID3D12Resource* pResourceBefore, _In_ ID3D12Resource* pResourceAfter) { CD3DX12_RESOURCE_BARRIER result; ZeroMemory(&result, sizeof(result)); D3D12_RESOURCE_BARRIER &barrier = result; result.Type = D3D12_RESOURCE_BARRIER_TYPE_ALIASING; barrier.Aliasing.pResourceBefore = pResourceBefore; barrier.Aliasing.pResourceAfter = pResourceAfter; return result; } static inline CD3DX12_RESOURCE_BARRIER UAV( _In_ ID3D12Resource* pResource) { CD3DX12_RESOURCE_BARRIER result; ZeroMemory(&result, sizeof(result)); D3D12_RESOURCE_BARRIER &barrier = result; result.Type = D3D12_RESOURCE_BARRIER_TYPE_UAV; barrier.UAV.pResource = pResource; return result; } operator const D3D12_RESOURCE_BARRIER&() const { return *this; } }; //------------------------------------------------------------------------------------------------ struct CD3DX12_PACKED_MIP_INFO : public D3D12_PACKED_MIP_INFO { CD3DX12_PACKED_MIP_INFO() {} explicit CD3DX12_PACKED_MIP_INFO(const D3D12_PACKED_MIP_INFO &o) : D3D12_PACKED_MIP_INFO(o) {} CD3DX12_PACKED_MIP_INFO( UINT8 numStandardMips, UINT8 numPackedMips, UINT numTilesForPackedMips, UINT startTileIndexInOverallResource) { NumStandardMips = numStandardMips; NumPackedMips = numPackedMips; NumTilesForPackedMips = numTilesForPackedMips; StartTileIndexInOverallResource = startTileIndexInOverallResource; } operator const D3D12_PACKED_MIP_INFO&() const { return *this; } }; //------------------------------------------------------------------------------------------------ struct CD3DX12_SUBRESOURCE_FOOTPRINT : public D3D12_SUBRESOURCE_FOOTPRINT { CD3DX12_SUBRESOURCE_FOOTPRINT() {} explicit CD3DX12_SUBRESOURCE_FOOTPRINT(const D3D12_SUBRESOURCE_FOOTPRINT &o) : D3D12_SUBRESOURCE_FOOTPRINT(o) {} CD3DX12_SUBRESOURCE_FOOTPRINT( DXGI_FORMAT format, UINT width, UINT height, UINT depth, UINT rowPitch) { Format = format; Width = width; Height = height; Depth = depth; RowPitch = rowPitch; } explicit CD3DX12_SUBRESOURCE_FOOTPRINT( const D3D12_RESOURCE_DESC& resDesc, UINT rowPitch) { Format = resDesc.Format; Width = UINT(resDesc.Width); Height = resDesc.Height; Depth = (resDesc.Dimension == D3D12_RESOURCE_DIMENSION_TEXTURE3D ? resDesc.DepthOrArraySize : 1); RowPitch = rowPitch; } operator const D3D12_SUBRESOURCE_FOOTPRINT&() const { return *this; } }; //------------------------------------------------------------------------------------------------ struct CD3DX12_TEXTURE_COPY_LOCATION : public D3D12_TEXTURE_COPY_LOCATION { CD3DX12_TEXTURE_COPY_LOCATION() {} explicit CD3DX12_TEXTURE_COPY_LOCATION(const D3D12_TEXTURE_COPY_LOCATION &o) : D3D12_TEXTURE_COPY_LOCATION(o) {} CD3DX12_TEXTURE_COPY_LOCATION(ID3D12Resource* pRes) { pResource = pRes; } CD3DX12_TEXTURE_COPY_LOCATION(ID3D12Resource* pRes, D3D12_PLACED_SUBRESOURCE_FOOTPRINT const& Footprint) { pResource = pRes; Type = D3D12_TEXTURE_COPY_TYPE_PLACED_FOOTPRINT; PlacedFootprint = Footprint; } CD3DX12_TEXTURE_COPY_LOCATION(ID3D12Resource* pRes, UINT Sub) { pResource = pRes; Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX; SubresourceIndex = Sub; } }; //------------------------------------------------------------------------------------------------ struct CD3DX12_DESCRIPTOR_RANGE : public D3D12_DESCRIPTOR_RANGE { CD3DX12_DESCRIPTOR_RANGE() { } explicit CD3DX12_DESCRIPTOR_RANGE(const D3D12_DESCRIPTOR_RANGE &o) : D3D12_DESCRIPTOR_RANGE(o) {} CD3DX12_DESCRIPTOR_RANGE( D3D12_DESCRIPTOR_RANGE_TYPE rangeType, UINT numDescriptors, UINT baseShaderRegister, UINT registerSpace = 0, UINT offsetInDescriptorsFromTableStart = D3D12_DESCRIPTOR_RANGE_OFFSET_APPEND) { Init(rangeType, numDescriptors, baseShaderRegister, registerSpace, offsetInDescriptorsFromTableStart); } inline void Init( D3D12_DESCRIPTOR_RANGE_TYPE rangeType, UINT numDescriptors, UINT baseShaderRegister, UINT registerSpace = 0, UINT offsetInDescriptorsFromTableStart = D3D12_DESCRIPTOR_RANGE_OFFSET_APPEND) { Init(*this, rangeType, numDescriptors, baseShaderRegister, registerSpace, offsetInDescriptorsFromTableStart); } static inline void Init( _Out_ D3D12_DESCRIPTOR_RANGE &range, D3D12_DESCRIPTOR_RANGE_TYPE rangeType, UINT numDescriptors, UINT baseShaderRegister, UINT registerSpace = 0, UINT offsetInDescriptorsFromTableStart = D3D12_DESCRIPTOR_RANGE_OFFSET_APPEND) { range.RangeType = rangeType; range.NumDescriptors = numDescriptors; range.BaseShaderRegister = baseShaderRegister; range.RegisterSpace = registerSpace; range.OffsetInDescriptorsFromTableStart = offsetInDescriptorsFromTableStart; } }; //------------------------------------------------------------------------------------------------ struct CD3DX12_ROOT_DESCRIPTOR_TABLE : public D3D12_ROOT_DESCRIPTOR_TABLE { CD3DX12_ROOT_DESCRIPTOR_TABLE() {} explicit CD3DX12_ROOT_DESCRIPTOR_TABLE(const D3D12_ROOT_DESCRIPTOR_TABLE &o) : D3D12_ROOT_DESCRIPTOR_TABLE(o) {} CD3DX12_ROOT_DESCRIPTOR_TABLE( UINT numDescriptorRanges, _In_reads_opt_(numDescriptorRanges) const D3D12_DESCRIPTOR_RANGE* _pDescriptorRanges) { Init(numDescriptorRanges, _pDescriptorRanges); } inline void Init( UINT numDescriptorRanges, _In_reads_opt_(numDescriptorRanges) const D3D12_DESCRIPTOR_RANGE* _pDescriptorRanges) { Init(*this, numDescriptorRanges, _pDescriptorRanges); } static inline void Init( _Out_ D3D12_ROOT_DESCRIPTOR_TABLE &rootDescriptorTable, UINT numDescriptorRanges, _In_reads_opt_(numDescriptorRanges) const D3D12_DESCRIPTOR_RANGE* _pDescriptorRanges) { rootDescriptorTable.NumDescriptorRanges = numDescriptorRanges; rootDescriptorTable.pDescriptorRanges = _pDescriptorRanges; } }; //------------------------------------------------------------------------------------------------ struct CD3DX12_ROOT_CONSTANTS : public D3D12_ROOT_CONSTANTS { CD3DX12_ROOT_CONSTANTS() {} explicit CD3DX12_ROOT_CONSTANTS(const D3D12_ROOT_CONSTANTS &o) : D3D12_ROOT_CONSTANTS(o) {} CD3DX12_ROOT_CONSTANTS( UINT num32BitValues, UINT shaderRegister, UINT registerSpace = 0) { Init(num32BitValues, shaderRegister, registerSpace); } inline void Init( UINT num32BitValues, UINT shaderRegister, UINT registerSpace = 0) { Init(*this, num32BitValues, shaderRegister, registerSpace); } static inline void Init( _Out_ D3D12_ROOT_CONSTANTS &rootConstants, UINT num32BitValues, UINT shaderRegister, UINT registerSpace = 0) { rootConstants.Num32BitValues = num32BitValues; rootConstants.ShaderRegister = shaderRegister; rootConstants.RegisterSpace = registerSpace; } }; //------------------------------------------------------------------------------------------------ struct CD3DX12_ROOT_DESCRIPTOR : public D3D12_ROOT_DESCRIPTOR { CD3DX12_ROOT_DESCRIPTOR() {} explicit CD3DX12_ROOT_DESCRIPTOR(const D3D12_ROOT_DESCRIPTOR &o) : D3D12_ROOT_DESCRIPTOR(o) {} CD3DX12_ROOT_DESCRIPTOR( UINT shaderRegister, UINT registerSpace = 0) { Init(shaderRegister, registerSpace); } inline void Init( UINT shaderRegister, UINT registerSpace = 0) { Init(*this, shaderRegister, registerSpace); } static inline void Init(_Out_ D3D12_ROOT_DESCRIPTOR &table, UINT shaderRegister, UINT registerSpace = 0) { table.ShaderRegister = shaderRegister; table.RegisterSpace = registerSpace; } }; //------------------------------------------------------------------------------------------------ struct CD3DX12_ROOT_PARAMETER : public D3D12_ROOT_PARAMETER { CD3DX12_ROOT_PARAMETER() {} explicit CD3DX12_ROOT_PARAMETER(const D3D12_ROOT_PARAMETER &o) : D3D12_ROOT_PARAMETER(o) {} static inline void InitAsDescriptorTable( _Out_ D3D12_ROOT_PARAMETER &rootParam, UINT numDescriptorRanges, _In_reads_(numDescriptorRanges) const D3D12_DESCRIPTOR_RANGE* pDescriptorRanges, D3D12_SHADER_VISIBILITY visibility = D3D12_SHADER_VISIBILITY_ALL) { rootParam.ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE; rootParam.ShaderVisibility = visibility; CD3DX12_ROOT_DESCRIPTOR_TABLE::Init(rootParam.DescriptorTable, numDescriptorRanges, pDescriptorRanges); } static inline void InitAsConstants( _Out_ D3D12_ROOT_PARAMETER &rootParam, UINT num32BitValues, UINT shaderRegister, UINT registerSpace = 0, D3D12_SHADER_VISIBILITY visibility = D3D12_SHADER_VISIBILITY_ALL) { rootParam.ParameterType = D3D12_ROOT_PARAMETER_TYPE_32BIT_CONSTANTS; rootParam.ShaderVisibility = visibility; CD3DX12_ROOT_CONSTANTS::Init(rootParam.Constants, num32BitValues, shaderRegister, registerSpace); } static inline void InitAsConstantBufferView( _Out_ D3D12_ROOT_PARAMETER &rootParam, UINT shaderRegister, UINT registerSpace = 0, D3D12_SHADER_VISIBILITY visibility = D3D12_SHADER_VISIBILITY_ALL) { rootParam.ParameterType = D3D12_ROOT_PARAMETER_TYPE_CBV; rootParam.ShaderVisibility = visibility; CD3DX12_ROOT_DESCRIPTOR::Init(rootParam.Descriptor, shaderRegister, registerSpace); } static inline void InitAsShaderResourceView( _Out_ D3D12_ROOT_PARAMETER &rootParam, UINT shaderRegister, UINT registerSpace = 0, D3D12_SHADER_VISIBILITY visibility = D3D12_SHADER_VISIBILITY_ALL) { rootParam.ParameterType = D3D12_ROOT_PARAMETER_TYPE_SRV; rootParam.ShaderVisibility = visibility; CD3DX12_ROOT_DESCRIPTOR::Init(rootParam.Descriptor, shaderRegister, registerSpace); } static inline void InitAsUnorderedAccessView( _Out_ D3D12_ROOT_PARAMETER &rootParam, UINT shaderRegister, UINT registerSpace = 0, D3D12_SHADER_VISIBILITY visibility = D3D12_SHADER_VISIBILITY_ALL) { rootParam.ParameterType = D3D12_ROOT_PARAMETER_TYPE_UAV; rootParam.ShaderVisibility = visibility; CD3DX12_ROOT_DESCRIPTOR::Init(rootParam.Descriptor, shaderRegister, registerSpace); } inline void InitAsDescriptorTable( UINT numDescriptorRanges, _In_reads_(numDescriptorRanges) const D3D12_DESCRIPTOR_RANGE* pDescriptorRanges, D3D12_SHADER_VISIBILITY visibility = D3D12_SHADER_VISIBILITY_ALL) { InitAsDescriptorTable(*this, numDescriptorRanges, pDescriptorRanges, visibility); } inline void InitAsConstants( UINT num32BitValues, UINT shaderRegister, UINT registerSpace = 0, D3D12_SHADER_VISIBILITY visibility = D3D12_SHADER_VISIBILITY_ALL) { InitAsConstants(*this, num32BitValues, shaderRegister, registerSpace, visibility); } inline void InitAsConstantBufferView( UINT shaderRegister, UINT registerSpace = 0, D3D12_SHADER_VISIBILITY visibility = D3D12_SHADER_VISIBILITY_ALL) { InitAsConstantBufferView(*this, shaderRegister, registerSpace, visibility); } inline void InitAsShaderResourceView( UINT shaderRegister, UINT registerSpace = 0, D3D12_SHADER_VISIBILITY visibility = D3D12_SHADER_VISIBILITY_ALL) { InitAsShaderResourceView(*this, shaderRegister, registerSpace, visibility); } inline void InitAsUnorderedAccessView( UINT shaderRegister, UINT registerSpace = 0, D3D12_SHADER_VISIBILITY visibility = D3D12_SHADER_VISIBILITY_ALL) { InitAsUnorderedAccessView(*this, shaderRegister, registerSpace, visibility); } }; //------------------------------------------------------------------------------------------------ struct CD3DX12_STATIC_SAMPLER_DESC : public D3D12_STATIC_SAMPLER_DESC { CD3DX12_STATIC_SAMPLER_DESC() {} explicit CD3DX12_STATIC_SAMPLER_DESC(const D3D12_STATIC_SAMPLER_DESC &o) : D3D12_STATIC_SAMPLER_DESC(o) {} CD3DX12_STATIC_SAMPLER_DESC( UINT shaderRegister, D3D12_FILTER filter = D3D12_FILTER_ANISOTROPIC, D3D12_TEXTURE_ADDRESS_MODE addressU = D3D12_TEXTURE_ADDRESS_MODE_WRAP, D3D12_TEXTURE_ADDRESS_MODE addressV = D3D12_TEXTURE_ADDRESS_MODE_WRAP, D3D12_TEXTURE_ADDRESS_MODE addressW = D3D12_TEXTURE_ADDRESS_MODE_WRAP, FLOAT mipLODBias = 0, UINT maxAnisotropy = 16, D3D12_COMPARISON_FUNC comparisonFunc = D3D12_COMPARISON_FUNC_LESS_EQUAL, D3D12_STATIC_BORDER_COLOR borderColor = D3D12_STATIC_BORDER_COLOR_OPAQUE_WHITE, FLOAT minLOD = 0.f, FLOAT maxLOD = D3D12_FLOAT32_MAX, D3D12_SHADER_VISIBILITY shaderVisibility = D3D12_SHADER_VISIBILITY_ALL, UINT registerSpace = 0) { Init( shaderRegister, filter, addressU, addressV, addressW, mipLODBias, maxAnisotropy, comparisonFunc, borderColor, minLOD, maxLOD, shaderVisibility, registerSpace); } static inline void Init( _Out_ D3D12_STATIC_SAMPLER_DESC &samplerDesc, UINT shaderRegister, D3D12_FILTER filter = D3D12_FILTER_ANISOTROPIC, D3D12_TEXTURE_ADDRESS_MODE addressU = D3D12_TEXTURE_ADDRESS_MODE_WRAP, D3D12_TEXTURE_ADDRESS_MODE addressV = D3D12_TEXTURE_ADDRESS_MODE_WRAP, D3D12_TEXTURE_ADDRESS_MODE addressW = D3D12_TEXTURE_ADDRESS_MODE_WRAP, FLOAT mipLODBias = 0, UINT maxAnisotropy = 16, D3D12_COMPARISON_FUNC comparisonFunc = D3D12_COMPARISON_FUNC_LESS_EQUAL, D3D12_STATIC_BORDER_COLOR borderColor = D3D12_STATIC_BORDER_COLOR_OPAQUE_WHITE, FLOAT minLOD = 0.f, FLOAT maxLOD = D3D12_FLOAT32_MAX, D3D12_SHADER_VISIBILITY shaderVisibility = D3D12_SHADER_VISIBILITY_ALL, UINT registerSpace = 0) { samplerDesc.ShaderRegister = shaderRegister; samplerDesc.Filter = filter; samplerDesc.AddressU = addressU; samplerDesc.AddressV = addressV; samplerDesc.AddressW = addressW; samplerDesc.MipLODBias = mipLODBias; samplerDesc.MaxAnisotropy = maxAnisotropy; samplerDesc.ComparisonFunc = comparisonFunc; samplerDesc.BorderColor = borderColor; samplerDesc.MinLOD = minLOD; samplerDesc.MaxLOD = maxLOD; samplerDesc.ShaderVisibility = shaderVisibility; samplerDesc.RegisterSpace = registerSpace; } inline void Init( UINT shaderRegister, D3D12_FILTER filter = D3D12_FILTER_ANISOTROPIC, D3D12_TEXTURE_ADDRESS_MODE addressU = D3D12_TEXTURE_ADDRESS_MODE_WRAP, D3D12_TEXTURE_ADDRESS_MODE addressV = D3D12_TEXTURE_ADDRESS_MODE_WRAP, D3D12_TEXTURE_ADDRESS_MODE addressW = D3D12_TEXTURE_ADDRESS_MODE_WRAP, FLOAT mipLODBias = 0, UINT maxAnisotropy = 16, D3D12_COMPARISON_FUNC comparisonFunc = D3D12_COMPARISON_FUNC_LESS_EQUAL, D3D12_STATIC_BORDER_COLOR borderColor = D3D12_STATIC_BORDER_COLOR_OPAQUE_WHITE, FLOAT minLOD = 0.f, FLOAT maxLOD = D3D12_FLOAT32_MAX, D3D12_SHADER_VISIBILITY shaderVisibility = D3D12_SHADER_VISIBILITY_ALL, UINT registerSpace = 0) { Init( *this, shaderRegister, filter, addressU, addressV, addressW, mipLODBias, maxAnisotropy, comparisonFunc, borderColor, minLOD, maxLOD, shaderVisibility, registerSpace); } }; //------------------------------------------------------------------------------------------------ struct CD3DX12_ROOT_SIGNATURE_DESC : public D3D12_ROOT_SIGNATURE_DESC { CD3DX12_ROOT_SIGNATURE_DESC() {} explicit CD3DX12_ROOT_SIGNATURE_DESC(const D3D12_ROOT_SIGNATURE_DESC &o) : D3D12_ROOT_SIGNATURE_DESC(o) {} CD3DX12_ROOT_SIGNATURE_DESC( UINT numParameters, _In_reads_opt_(numParameters) const D3D12_ROOT_PARAMETER* _pParameters, UINT numStaticSamplers = 0, _In_reads_opt_(numStaticSamplers) const D3D12_STATIC_SAMPLER_DESC* _pStaticSamplers = NULL, D3D12_ROOT_SIGNATURE_FLAGS flags = D3D12_ROOT_SIGNATURE_FLAG_NONE) { Init(numParameters, _pParameters, numStaticSamplers, _pStaticSamplers, flags); } CD3DX12_ROOT_SIGNATURE_DESC(CD3DX12_DEFAULT) { Init(0, NULL, 0, NULL, D3D12_ROOT_SIGNATURE_FLAG_NONE); } inline void Init( UINT numParameters, _In_reads_opt_(numParameters) const D3D12_ROOT_PARAMETER* _pParameters, UINT numStaticSamplers = 0, _In_reads_opt_(numStaticSamplers) const D3D12_STATIC_SAMPLER_DESC* _pStaticSamplers = NULL, D3D12_ROOT_SIGNATURE_FLAGS flags = D3D12_ROOT_SIGNATURE_FLAG_NONE) { Init(*this, numParameters, _pParameters, numStaticSamplers, _pStaticSamplers, flags); } static inline void Init( _Out_ D3D12_ROOT_SIGNATURE_DESC &desc, UINT numParameters, _In_reads_opt_(numParameters) const D3D12_ROOT_PARAMETER* _pParameters, UINT numStaticSamplers = 0, _In_reads_opt_(numStaticSamplers) const D3D12_STATIC_SAMPLER_DESC* _pStaticSamplers = NULL, D3D12_ROOT_SIGNATURE_FLAGS flags = D3D12_ROOT_SIGNATURE_FLAG_NONE) { desc.NumParameters = numParameters; desc.pParameters = _pParameters; desc.NumStaticSamplers = numStaticSamplers; desc.pStaticSamplers = _pStaticSamplers; desc.Flags = flags; } }; //------------------------------------------------------------------------------------------------ struct CD3DX12_CPU_DESCRIPTOR_HANDLE : public D3D12_CPU_DESCRIPTOR_HANDLE { CD3DX12_CPU_DESCRIPTOR_HANDLE() {} explicit CD3DX12_CPU_DESCRIPTOR_HANDLE(const D3D12_CPU_DESCRIPTOR_HANDLE &o) : D3D12_CPU_DESCRIPTOR_HANDLE(o) {} CD3DX12_CPU_DESCRIPTOR_HANDLE(CD3DX12_DEFAULT) { ptr = 0; } CD3DX12_CPU_DESCRIPTOR_HANDLE(_In_ const D3D12_CPU_DESCRIPTOR_HANDLE &other, INT offsetScaledByIncrementSize) { InitOffsetted(other, offsetScaledByIncrementSize); } CD3DX12_CPU_DESCRIPTOR_HANDLE(_In_ const D3D12_CPU_DESCRIPTOR_HANDLE &other, INT offsetInDescriptors, UINT descriptorIncrementSize) { InitOffsetted(other, offsetInDescriptors, descriptorIncrementSize); } CD3DX12_CPU_DESCRIPTOR_HANDLE& Offset(INT offsetInDescriptors, UINT descriptorIncrementSize) { ptr += offsetInDescriptors * descriptorIncrementSize; return *this; } CD3DX12_CPU_DESCRIPTOR_HANDLE& Offset(INT offsetScaledByIncrementSize) { ptr += offsetScaledByIncrementSize; return *this; } bool operator==(_In_ const D3D12_CPU_DESCRIPTOR_HANDLE& other) { return (ptr == other.ptr); } bool operator!=(_In_ const D3D12_CPU_DESCRIPTOR_HANDLE& other) { return (ptr != other.ptr); } CD3DX12_CPU_DESCRIPTOR_HANDLE &operator=(const D3D12_CPU_DESCRIPTOR_HANDLE &other) { ptr = other.ptr; return *this; } inline void InitOffsetted(_In_ const D3D12_CPU_DESCRIPTOR_HANDLE &base, INT offsetScaledByIncrementSize) { InitOffsetted(*this, base, offsetScaledByIncrementSize); } inline void InitOffsetted(_In_ const D3D12_CPU_DESCRIPTOR_HANDLE &base, INT offsetInDescriptors, UINT descriptorIncrementSize) { InitOffsetted(*this, base, offsetInDescriptors, descriptorIncrementSize); } static inline void InitOffsetted(_Out_ D3D12_CPU_DESCRIPTOR_HANDLE &handle, _In_ const D3D12_CPU_DESCRIPTOR_HANDLE &base, INT offsetScaledByIncrementSize) { handle.ptr = base.ptr + offsetScaledByIncrementSize; } static inline void InitOffsetted(_Out_ D3D12_CPU_DESCRIPTOR_HANDLE &handle, _In_ const D3D12_CPU_DESCRIPTOR_HANDLE &base, INT offsetInDescriptors, UINT descriptorIncrementSize) { handle.ptr = base.ptr + offsetInDescriptors * descriptorIncrementSize; } }; //------------------------------------------------------------------------------------------------ struct CD3DX12_GPU_DESCRIPTOR_HANDLE : public D3D12_GPU_DESCRIPTOR_HANDLE { CD3DX12_GPU_DESCRIPTOR_HANDLE() {} explicit CD3DX12_GPU_DESCRIPTOR_HANDLE(const D3D12_GPU_DESCRIPTOR_HANDLE &o) : D3D12_GPU_DESCRIPTOR_HANDLE(o) {} CD3DX12_GPU_DESCRIPTOR_HANDLE(CD3DX12_DEFAULT) { ptr = 0; } CD3DX12_GPU_DESCRIPTOR_HANDLE(_In_ const D3D12_GPU_DESCRIPTOR_HANDLE &other, INT offsetScaledByIncrementSize) { InitOffsetted(other, offsetScaledByIncrementSize); } CD3DX12_GPU_DESCRIPTOR_HANDLE(_In_ const D3D12_GPU_DESCRIPTOR_HANDLE &other, INT offsetInDescriptors, UINT descriptorIncrementSize) { InitOffsetted(other, offsetInDescriptors, descriptorIncrementSize); } CD3DX12_GPU_DESCRIPTOR_HANDLE& Offset(INT offsetInDescriptors, UINT descriptorIncrementSize) { ptr += offsetInDescriptors * descriptorIncrementSize; return *this; } CD3DX12_GPU_DESCRIPTOR_HANDLE& Offset(INT offsetScaledByIncrementSize) { ptr += offsetScaledByIncrementSize; return *this; } inline bool operator==(_In_ const D3D12_GPU_DESCRIPTOR_HANDLE& other) { return (ptr == other.ptr); } inline bool operator!=(_In_ const D3D12_GPU_DESCRIPTOR_HANDLE& other) { return (ptr != other.ptr); } CD3DX12_GPU_DESCRIPTOR_HANDLE &operator=(const D3D12_GPU_DESCRIPTOR_HANDLE &other) { ptr = other.ptr; return *this; } inline void InitOffsetted(_In_ const D3D12_GPU_DESCRIPTOR_HANDLE &base, INT offsetScaledByIncrementSize) { InitOffsetted(*this, base, offsetScaledByIncrementSize); } inline void InitOffsetted(_In_ const D3D12_GPU_DESCRIPTOR_HANDLE &base, INT offsetInDescriptors, UINT descriptorIncrementSize) { InitOffsetted(*this, base, offsetInDescriptors, descriptorIncrementSize); } static inline void InitOffsetted(_Out_ D3D12_GPU_DESCRIPTOR_HANDLE &handle, _In_ const D3D12_GPU_DESCRIPTOR_HANDLE &base, INT offsetScaledByIncrementSize) { handle.ptr = base.ptr + offsetScaledByIncrementSize; } static inline void InitOffsetted(_Out_ D3D12_GPU_DESCRIPTOR_HANDLE &handle, _In_ const D3D12_GPU_DESCRIPTOR_HANDLE &base, INT offsetInDescriptors, UINT descriptorIncrementSize) { handle.ptr = base.ptr + offsetInDescriptors * descriptorIncrementSize; } }; //------------------------------------------------------------------------------------------------ inline UINT D3D12CalcSubresource(UINT MipSlice, UINT ArraySlice, UINT PlaneSlice, UINT MipLevels, UINT ArraySize) { return MipSlice + ArraySlice * MipLevels + PlaneSlice * MipLevels * ArraySize; } //------------------------------------------------------------------------------------------------ template inline void D3D12DecomposeSubresource(UINT Subresource, UINT MipLevels, UINT ArraySize, _Out_ T& MipSlice, _Out_ U& ArraySlice, _Out_ V& PlaneSlice) { MipSlice = static_cast(Subresource % MipLevels); ArraySlice = static_cast((Subresource / MipLevels) % ArraySize); PlaneSlice = static_cast(Subresource / (MipLevels * ArraySize)); } //------------------------------------------------------------------------------------------------ inline UINT8 D3D12GetFormatPlaneCount( _In_ ID3D12Device* pDevice, DXGI_FORMAT Format ) { D3D12_FEATURE_DATA_FORMAT_INFO formatInfo = { Format }; if (FAILED(pDevice->CheckFeatureSupport(D3D12_FEATURE_FORMAT_INFO, &formatInfo, sizeof(formatInfo)))) { return 0; } return formatInfo.PlaneCount; } //------------------------------------------------------------------------------------------------ struct CD3DX12_RESOURCE_DESC : public D3D12_RESOURCE_DESC { CD3DX12_RESOURCE_DESC() {} explicit CD3DX12_RESOURCE_DESC(const D3D12_RESOURCE_DESC& o) : D3D12_RESOURCE_DESC(o) {} CD3DX12_RESOURCE_DESC( D3D12_RESOURCE_DIMENSION dimension, UINT64 alignment, UINT64 width, UINT height, UINT16 depthOrArraySize, UINT16 mipLevels, DXGI_FORMAT format, UINT sampleCount, UINT sampleQuality, D3D12_TEXTURE_LAYOUT layout, D3D12_RESOURCE_FLAGS flags) { Dimension = dimension; Alignment = alignment; Width = width; Height = height; DepthOrArraySize = depthOrArraySize; MipLevels = mipLevels; Format = format; SampleDesc.Count = sampleCount; SampleDesc.Quality = sampleQuality; Layout = layout; Flags = flags; } static inline CD3DX12_RESOURCE_DESC Buffer( const D3D12_RESOURCE_ALLOCATION_INFO& resAllocInfo, D3D12_RESOURCE_FLAGS flags = D3D12_RESOURCE_FLAG_NONE) { return CD3DX12_RESOURCE_DESC(D3D12_RESOURCE_DIMENSION_BUFFER, resAllocInfo.Alignment, resAllocInfo.SizeInBytes, 1, 1, 1, DXGI_FORMAT_UNKNOWN, 1, 0, D3D12_TEXTURE_LAYOUT_ROW_MAJOR, flags); } static inline CD3DX12_RESOURCE_DESC Buffer( UINT64 width, D3D12_RESOURCE_FLAGS flags = D3D12_RESOURCE_FLAG_NONE, UINT64 alignment = 0) { return CD3DX12_RESOURCE_DESC(D3D12_RESOURCE_DIMENSION_BUFFER, alignment, width, 1, 1, 1, DXGI_FORMAT_UNKNOWN, 1, 0, D3D12_TEXTURE_LAYOUT_ROW_MAJOR, flags); } static inline CD3DX12_RESOURCE_DESC Tex1D( DXGI_FORMAT format, UINT64 width, UINT16 arraySize = 1, UINT16 mipLevels = 0, D3D12_RESOURCE_FLAGS flags = D3D12_RESOURCE_FLAG_NONE, D3D12_TEXTURE_LAYOUT layout = D3D12_TEXTURE_LAYOUT_UNKNOWN, UINT64 alignment = 0) { return CD3DX12_RESOURCE_DESC(D3D12_RESOURCE_DIMENSION_TEXTURE1D, alignment, width, 1, arraySize, mipLevels, format, 1, 0, layout, flags); } static inline CD3DX12_RESOURCE_DESC Tex2D( DXGI_FORMAT format, UINT64 width, UINT height, UINT16 arraySize = 1, UINT16 mipLevels = 0, UINT sampleCount = 1, UINT sampleQuality = 0, D3D12_RESOURCE_FLAGS flags = D3D12_RESOURCE_FLAG_NONE, D3D12_TEXTURE_LAYOUT layout = D3D12_TEXTURE_LAYOUT_UNKNOWN, UINT64 alignment = 0) { return CD3DX12_RESOURCE_DESC(D3D12_RESOURCE_DIMENSION_TEXTURE2D, alignment, width, height, arraySize, mipLevels, format, sampleCount, sampleQuality, layout, flags); } static inline CD3DX12_RESOURCE_DESC Tex3D( DXGI_FORMAT format, UINT64 width, UINT height, UINT16 depth, UINT16 mipLevels = 0, D3D12_RESOURCE_FLAGS flags = D3D12_RESOURCE_FLAG_NONE, D3D12_TEXTURE_LAYOUT layout = D3D12_TEXTURE_LAYOUT_UNKNOWN, UINT64 alignment = 0) { return CD3DX12_RESOURCE_DESC(D3D12_RESOURCE_DIMENSION_TEXTURE3D, alignment, width, height, depth, mipLevels, format, 1, 0, layout, flags); } inline UINT16 Depth() const { return (Dimension == D3D12_RESOURCE_DIMENSION_TEXTURE3D ? DepthOrArraySize : 1); } inline UINT16 ArraySize() const { return (Dimension != D3D12_RESOURCE_DIMENSION_TEXTURE3D ? DepthOrArraySize : 1); } inline UINT8 PlaneCount(_In_ ID3D12Device* pDevice) const { return D3D12GetFormatPlaneCount(pDevice, Format); } inline UINT Subresources(_In_ ID3D12Device* pDevice) const { return MipLevels * ArraySize() * PlaneCount(pDevice); } inline UINT CalcSubresource(UINT MipSlice, UINT ArraySlice, UINT PlaneSlice) { return D3D12CalcSubresource(MipSlice, ArraySlice, PlaneSlice, MipLevels, ArraySize()); } operator const D3D12_RESOURCE_DESC&() const { return *this; } }; inline bool operator==(const D3D12_RESOURCE_DESC& l, const D3D12_RESOURCE_DESC& r) { return l.Dimension == r.Dimension && l.Alignment == r.Alignment && l.Width == r.Width && l.Height == r.Height && l.DepthOrArraySize == r.DepthOrArraySize && l.MipLevels == r.MipLevels && l.Format == r.Format && l.SampleDesc.Count == r.SampleDesc.Count && l.SampleDesc.Quality == r.SampleDesc.Quality && l.Layout == r.Layout && l.Flags == r.Flags; } inline bool operator!=(const D3D12_RESOURCE_DESC& l, const D3D12_RESOURCE_DESC& r) { return !(l == r); } //------------------------------------------------------------------------------------------------ // Row-by-row memcpy inline void MemcpySubresource( _In_ const D3D12_MEMCPY_DEST* pDest, _In_ const D3D12_SUBRESOURCE_DATA* pSrc, SIZE_T RowSizeInBytes, UINT NumRows, UINT NumSlices) { for (UINT z = 0; z < NumSlices; ++z) { BYTE* pDestSlice = reinterpret_cast(pDest->pData) + pDest->SlicePitch * z; const BYTE* pSrcSlice = reinterpret_cast(pSrc->pData) + pSrc->SlicePitch * z; for (UINT y = 0; y < NumRows; ++y) { memcpy(pDestSlice + pDest->RowPitch * y, pSrcSlice + pSrc->RowPitch * y, RowSizeInBytes); } } } //------------------------------------------------------------------------------------------------ // Returns required size of a buffer to be used for data upload inline UINT64 GetRequiredIntermediateSize( _In_ ID3D12Resource* pDestinationResource, _In_range_(0, D3D12_REQ_SUBRESOURCES) UINT FirstSubresource, _In_range_(0, D3D12_REQ_SUBRESOURCES - FirstSubresource) UINT NumSubresources) { D3D12_RESOURCE_DESC Desc = pDestinationResource->GetDesc(); UINT64 RequiredSize = 0; ID3D12Device* pDevice; pDestinationResource->GetDevice(__uuidof(*pDevice), reinterpret_cast(&pDevice)); pDevice->GetCopyableFootprints(&Desc, FirstSubresource, NumSubresources, 0, nullptr, nullptr, nullptr, &RequiredSize); pDevice->Release(); return RequiredSize; } //------------------------------------------------------------------------------------------------ // All arrays must be populated (e.g. by calling GetCopyableFootprints) inline UINT64 UpdateSubresources( _In_ ID3D12GraphicsCommandList* pCmdList, _In_ ID3D12Resource* pDestinationResource, _In_ ID3D12Resource* pIntermediate, _In_range_(0, D3D12_REQ_SUBRESOURCES) UINT FirstSubresource, _In_range_(0, D3D12_REQ_SUBRESOURCES - FirstSubresource) UINT NumSubresources, UINT64 RequiredSize, _In_reads_(NumSubresources) const D3D12_PLACED_SUBRESOURCE_FOOTPRINT* pLayouts, _In_reads_(NumSubresources) const UINT* pNumRows, _In_reads_(NumSubresources) const UINT64* pRowSizesInBytes, _In_reads_(NumSubresources) const D3D12_SUBRESOURCE_DATA* pSrcData) { // Minor validation D3D12_RESOURCE_DESC IntermediateDesc = pIntermediate->GetDesc(); D3D12_RESOURCE_DESC DestinationDesc = pDestinationResource->GetDesc(); if (IntermediateDesc.Dimension != D3D12_RESOURCE_DIMENSION_BUFFER || IntermediateDesc.Width < RequiredSize + pLayouts[0].Offset || RequiredSize >(SIZE_T) - 1 || (DestinationDesc.Dimension == D3D12_RESOURCE_DIMENSION_BUFFER && (FirstSubresource != 0 || NumSubresources != 1))) { return 0; } BYTE* pData; HRESULT hr = pIntermediate->Map(0, NULL, reinterpret_cast(&pData)); if (FAILED(hr)) { return 0; } for (UINT i = 0; i < NumSubresources; ++i) { if (pRowSizesInBytes[i] >(SIZE_T)-1) return 0; D3D12_MEMCPY_DEST DestData = { pData + pLayouts[i].Offset, pLayouts[i].Footprint.RowPitch, pLayouts[i].Footprint.RowPitch * pNumRows[i] }; MemcpySubresource(&DestData, &pSrcData[i], (SIZE_T)pRowSizesInBytes[i], pNumRows[i], pLayouts[i].Footprint.Depth); } pIntermediate->Unmap(0, NULL); if (DestinationDesc.Dimension == D3D12_RESOURCE_DIMENSION_BUFFER) { CD3DX12_BOX SrcBox(UINT(pLayouts[0].Offset), UINT(pLayouts[0].Offset + pLayouts[0].Footprint.Width)); pCmdList->CopyBufferRegion( pDestinationResource, 0, pIntermediate, pLayouts[0].Offset, pLayouts[0].Footprint.Width); } else { for (UINT i = 0; i < NumSubresources; ++i) { CD3DX12_TEXTURE_COPY_LOCATION Dst(pDestinationResource, i + FirstSubresource); CD3DX12_TEXTURE_COPY_LOCATION Src(pIntermediate, pLayouts[i]); pCmdList->CopyTextureRegion(&Dst, 0, 0, 0, &Src, nullptr); } } return RequiredSize; } //------------------------------------------------------------------------------------------------ // Heap-allocating UpdateSubresources implementation inline UINT64 UpdateSubresources( _In_ ID3D12GraphicsCommandList* pCmdList, _In_ ID3D12Resource* pDestinationResource, _In_ ID3D12Resource* pIntermediate, UINT64 IntermediateOffset, _In_range_(0, D3D12_REQ_SUBRESOURCES) UINT FirstSubresource, _In_range_(0, D3D12_REQ_SUBRESOURCES - FirstSubresource) UINT NumSubresources, _In_reads_(NumSubresources) D3D12_SUBRESOURCE_DATA* pSrcData) { UINT64 RequiredSize = 0; UINT64 MemToAlloc = static_cast(sizeof(D3D12_PLACED_SUBRESOURCE_FOOTPRINT) + sizeof(UINT) + sizeof(UINT64)) * NumSubresources; if (MemToAlloc > SIZE_MAX) { return 0; } void* pMem = HeapAlloc(GetProcessHeap(), 0, static_cast(MemToAlloc)); if (pMem == NULL) { return 0; } D3D12_PLACED_SUBRESOURCE_FOOTPRINT* pLayouts = reinterpret_cast(pMem); UINT64* pRowSizesInBytes = reinterpret_cast(pLayouts + NumSubresources); UINT* pNumRows = reinterpret_cast(pRowSizesInBytes + NumSubresources); D3D12_RESOURCE_DESC Desc = pDestinationResource->GetDesc(); ID3D12Device* pDevice; pDestinationResource->GetDevice(__uuidof(*pDevice), reinterpret_cast(&pDevice)); pDevice->GetCopyableFootprints(&Desc, FirstSubresource, NumSubresources, IntermediateOffset, pLayouts, pNumRows, pRowSizesInBytes, &RequiredSize); pDevice->Release(); UINT64 Result = UpdateSubresources(pCmdList, pDestinationResource, pIntermediate, FirstSubresource, NumSubresources, RequiredSize, pLayouts, pNumRows, pRowSizesInBytes, pSrcData); HeapFree(GetProcessHeap(), 0, pMem); return Result; } //------------------------------------------------------------------------------------------------ // Stack-allocating UpdateSubresources implementation template inline UINT64 UpdateSubresources( _In_ ID3D12GraphicsCommandList* pCmdList, _In_ ID3D12Resource* pDestinationResource, _In_ ID3D12Resource* pIntermediate, UINT64 IntermediateOffset, _In_range_(0, MaxSubresources) UINT FirstSubresource, _In_range_(1, MaxSubresources - FirstSubresource) UINT NumSubresources, _In_reads_(NumSubresources) D3D12_SUBRESOURCE_DATA* pSrcData) { UINT64 RequiredSize = 0; D3D12_PLACED_SUBRESOURCE_FOOTPRINT Layouts[MaxSubresources]; UINT NumRows[MaxSubresources]; UINT64 RowSizesInBytes[MaxSubresources]; D3D12_RESOURCE_DESC Desc = pDestinationResource->GetDesc(); ID3D12Device* pDevice; pDestinationResource->GetDevice(__uuidof(*pDevice), reinterpret_cast(&pDevice)); pDevice->GetCopyableFootprints(&Desc, FirstSubresource, NumSubresources, IntermediateOffset, Layouts, NumRows, RowSizesInBytes, &RequiredSize); pDevice->Release(); return UpdateSubresources(pCmdList, pDestinationResource, pIntermediate, FirstSubresource, NumSubresources, RequiredSize, Layouts, NumRows, RowSizesInBytes, pSrcData); } //------------------------------------------------------------------------------------------------ inline bool D3D12IsLayoutOpaque(D3D12_TEXTURE_LAYOUT Layout) { return Layout == D3D12_TEXTURE_LAYOUT_UNKNOWN || Layout == D3D12_TEXTURE_LAYOUT_64KB_UNDEFINED_SWIZZLE; } //------------------------------------------------------------------------------------------------ inline ID3D12CommandList * const * CommandListCast(ID3D12GraphicsCommandList * const * pp) { // This cast is useful for passing strongly typed command list pointers into // ExecuteCommandLists. // This cast is valid as long as the const-ness is respected. D3D12 APIs do // respect the const-ness of their arguments. return reinterpret_cast(pp); } #endif // defined( __cplusplus ) #endif //__D3DX12_H__ ================================================ FILE: src/mainfrm.h ================================================ #include "trayicon.h" #include "D3dx12jo.h" // User defined Constants: #define WM_TPSCREENSAVER WM_USER + 0x05 ////////////////// // Main frame for TRAYTEST. // class CMainFrame : public CFrameWnd { public: BOOL MonitorOffSupport(); CMainFrame(); BOOL IsShiftKeyDown(); D3dx12jo* m_pD3jo; virtual ~CMainFrame(); protected: DECLARE_DYNAMIC(CMainFrame) CStatusBar m_wndStatusBar; CTrayIcon m_trayIcon; // my tray icon //CEdit m_wndEdit; // to display tray notifications int m_iWhichIcon; // 0/1 which HICON to use BOOL m_bShutdown; // OK to terminate TRAYTEST //BOOL m_bShowTrayNotifications; // display info in main window //{{AFX_MSG(CMainFrame) afx_msg LRESULT OnTrayNotification(WPARAM wp, LPARAM lp); afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct); afx_msg void OnClose(); afx_msg void OnAppTpExit(); afx_msg void OnTpLogOff(); afx_msg void OnTpShutDown(); afx_msg void OnTpRestart(); afx_msg void OnTpStandBy(); afx_msg void OnTimer(UINT_PTR nIDEvent); afx_msg void OnTpScreenSave(); afx_msg void OnEndSession(BOOL bEnding); void ResetTimerTicks(); //}}AFX_MSG DECLARE_MESSAGE_MAP() private: void DoMenuDropDown(); UINT_PTR m_nTimer; UINT m_BtnClicked; UINT m_nTicks; UINT m_DblClicked; void OnStopTimer(); void OnStartTimer(); void TpExitWindows(BOOL Force,int shtdn); }; ================================================ FILE: src/res/APP.RC2 ================================================ // // APP.RC2 - resources Microsoft Visual C++ does not edit directly // #ifdef APSTUDIO_INVOKED #error this file is not editable by Microsoft Visual C++ #endif //APSTUDIO_INVOKED ///////////////////////////////////////////////////////////////////////////// // Add manually edited resources here... ///////////////////////////////////////////////////////////////////////////// ================================================ FILE: src/resource.h ================================================ //{{NO_DEPENDENCIES}} // Microsoft Visual C++ generated include file. // Used by TrayPwr.rc // #define IDR_MAINFRAME 2 #define IDR_TRAYICON 3 #define IDSYSINFO 81 #define IDD_ABOUTBOX 100 #define IDI_MYICON 101 #define IDI_MYICON2 102 #define IDC_EDIT1 1002 #define IDC_EDITLIC 1002 #define ID_APPTP_EXIT 32776 #define ID_TPLOGOFF 32777 #define ID_TPSHUTDOWN 32778 #define ID_TPRESTART 32779 #define ID_TPSTANDBY 32780 #define ID_TPSCREENSAVE 32781 // Next default values for new objects // #ifdef APSTUDIO_INVOKED #ifndef APSTUDIO_READONLY_SYMBOLS #define _APS_NEXT_RESOURCE_VALUE 105 #define _APS_NEXT_COMMAND_VALUE 32781 #define _APS_NEXT_CONTROL_VALUE 1003 #define _APS_NEXT_SYMED_VALUE 103 #endif #endif ================================================ FILE: src/stdafx.cpp ================================================ #include "stdafx.h" ================================================ FILE: src/stdafx.h ================================================ #pragma once #ifndef WIN32_LEAN_AND_MEAN #define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers. #endif #include // MFC core and standard components #include // MFC extensions (including VB) #include ================================================ FILE: src/trayicon.h ================================================ //////////////////////////////////////////////////////////////// // CTrayIcon Copyright 1996 Microsoft Systems Journal. // // If this code works, it was written by Paul DiLascia. // If not, I don't know who wrote it. #ifndef _TRAYICON_H #define _TRAYICON_H //////////////// // CTrayIcon manages an icon in the Windows 95 system tray. // class CTrayIcon : public CCmdTarget { protected: DECLARE_DYNAMIC(CTrayIcon) NOTIFYICONDATA m_nid; // struct for Shell_NotifyIcon args public: CTrayIcon(UINT uID); ~CTrayIcon(); // Call this to receive tray notifications void SetNotificationWnd(CWnd* pNotifyWnd, UINT uCbMsg); // SetIcon functions. To remove icon, call SetIcon(0) // BOOL SetIcon(UINT uID); // main variant you want to use BOOL SetIcon(HICON hicon, LPCSTR lpTip); BOOL SetIcon(LPCTSTR lpResName, LPCSTR lpTip) { return SetIcon(lpResName ? AfxGetApp()->LoadIcon(lpResName) : NULL, lpTip); } BOOL SetStandardIcon(LPCTSTR lpszIconName, LPCSTR lpTip) { return SetIcon(::LoadIcon(NULL, lpszIconName), lpTip); } }; #endif