C++/cli override OnRender Event wpf - c++

i try to bring a wpf "fire" (http://www.smartypantscoding.com/content/old-school-fire-algorithm-modern-day-wpf) Example to c++/cli. I translated it with a tool to c++/cli, but the overriden "OnRender" Event never get fired. So i see the Window like in the c# Project but without fire.
CompositionTarget_Rendering get called, and so normally InvalidateVisual() must fire the OnRender, but it doesn't. I hope u can help me =)
//the .h
#pragma once
using namespace System;
using namespace System::Collections;
using namespace System::Collections::Generic;
using namespace System::Globalization;
using namespace System::Xml::Linq;
using namespace System::Text;
using namespace System::Windows::Documents;
using namespace System::Windows;
using namespace System::Windows::Media;
using namespace System::Windows::Media::Imaging;
using namespace System::Threading;
#include "FireGenerator.h"
/// <summary>
/// Adorner that disables all controls that fall under it
/// </summary>
public ref class FireAdorner : Adorner
{
private:
BitmapPalette ^_pallette;
literal int DPI = 96;
FireGenerator ^_fireGenerator;
/// <summary>
/// Constructor for the adorner
/// </summary>
/// <param name="adornerElement">The element to be adorned</param>
public:
FireAdorner(UIElement^ adornerElement);
private:
void CompositionTarget_Rendering(Object ^sender, EventArgs ^e);
/// <summary>
/// Called to draw on screen
/// </summary>
/// <param name="drawingContext">The drawind context in which we can draw</param>
protected:
virtual void OnRender(System::Windows::Media::DrawingContext ^drawingContext) override;
private:
BitmapPalette ^SetupFirePalette();
private:
void InitializeInstanceFields();
};
and the .cpp
#include "StdAfx.h"
#include "FireAdorner.h"
using namespace System;
using namespace System::Collections;
using namespace System::Collections::Generic;
using namespace System::Globalization;
using namespace System::Xml::Linq;
using namespace System::Text;
using namespace System::Windows::Documents;
using namespace System::Windows;
using namespace System::Windows::Media;
using namespace System::Windows::Media::Imaging;
using namespace System::Threading;
FireAdorner::FireAdorner(UIElement ^adornerElement) : Adorner(adornerElement)
{
InitializeInstanceFields();
CompositionTarget::Rendering += gcnew EventHandler(this, &FireAdorner::CompositionTarget_Rendering);
}
void FireAdorner::CompositionTarget_Rendering(Object ^sender, EventArgs ^e)
{
InvalidateVisual();
}
void FireAdorner::OnRender(System::Windows::Media::DrawingContext ^drawingContext)
{
System::Windows::MessageBox::Show("render");
// only set the pallette once (dont do in constructor as causes odd errors if exception occurs)
if (_pallette == nullptr)
{
_pallette = SetupFirePalette();
}
_fireGenerator->UpdateFire();
BitmapSource ^bs = BitmapSource::Create(_fireGenerator->Width, _fireGenerator->Height, DPI, DPI, PixelFormats::Indexed8, _pallette, _fireGenerator->FireData, _fireGenerator->Width);
drawingContext->DrawImage(bs, Rect(0, 0, this->DesiredSize.Width, this->DesiredSize.Height));
}
BitmapPalette ^FireAdorner::SetupFirePalette()
{
System::Collections::Generic::List<Color> ^myList = gcnew System::Collections::Generic::List<Color>();
// seutp the basic array we will modify
for (int i = 0; i <= 255; i++)
{
myList->Add(Color());
}
for (int i = 0; i < 64; i++)
{
Color c1 = Color();
c1.R = safe_cast<Byte>(i * 4);
c1.G = safe_cast<Byte>(0);
c1.B = safe_cast<Byte>(0);
c1.A = 255;
myList[i] = c1;
Color c2 = Color();
c2.R = safe_cast<Byte>(255);
c2.G = safe_cast<Byte>(i * 4);
c2.B = safe_cast<Byte>(0);
c2.A = 255;
myList[i + 64] = c2;
Color c3 = Color();
c3.R = safe_cast<Byte>(255);
c3.G = safe_cast<Byte>(255);
c3.B = safe_cast<Byte>(i * 4);
c3.A = 255;
myList[i + 128] = c3;
Color c4 = Color();
c4.R = safe_cast<Byte>(255);
c4.G = safe_cast<Byte>(255);
c4.B = safe_cast<Byte>(255);
c4.A = 255;
myList[i + 192] = c4;
}
BitmapPalette ^bp = gcnew BitmapPalette(myList);
return bp;
}
void FireAdorner::InitializeInstanceFields()
{
_fireGenerator = gcnew FireGenerator(600, 50);
}
Initcode:
FireAdorner^ myfire = gcnew FireAdorner(MyWindow);
MyWindow->ShowDialog();
//MyWindow is a Window^ created from this Code:
<Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="WPF Fire" Width="800" Height="200" Closing="Window_Closing">
<Grid>
<AdornerDecorator>
<DockPanel Name="dockPanel1"/>
</AdornerDecorator>
<!-- This rectangle is a hack to hide the bottom rows of the fire which look blocky
the proper solution would be to fix the rendering to leave off the bottom XX lines -->
<Rectangle Fill="Black" VerticalAlignment="Bottom"
Width="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=Window}, Path=ActualWidth}"
Height="8" />
</Grid>
</Window>

This solved the Problem:
old not working Initcode:
FireAdorner^ myfire = gcnew FireAdorner(MyWindow);
MyWindow->ShowDialog();
new Initcode:
DockPanel^ firebox = (DockPanel^)MyWindow->FindName("dockPanel1");
AdornerLayer^ adornerLayer = AdornerLayer::GetAdornerLayer(firebox);
adornerLayer->Add(gcnew FireAdorner(firebox));
MyWindow->ShowDialog();

Related

Blueprint loop/for/while node with custom c++ blueprint function library in unreal engine 4 (ue4)

I need to create a custom blueprint node. I am using the blueprint function library.
The node will look like this:
Input:
int timedelayforeachloop
int numberofloops
output:
exc loop
exc completed
loop1.h
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "Kismet/BlueprintFunctionLibrary.h"
#include "loop1.generated.h"
/**
*
*/
UENUM(BlueprintType)
enum class EMultiBranchEnum1 : uint8
{
BranchA,
BranchB
};
UCLASS()
class MYPROJECT2_API Uloop1 : public UBlueprintFunctionLibrary
{
GENERATED_BODY()
UFUNCTION(BlueprintCallable, meta = (DisplayName = "loop", CompactNodeTitle = "2as2", ExpandEnumAsExecs = "Branches"), Category = "1")
//UFUNCTION(BlueprintCallable, Meta = (DisplayName = "Multi Branch1", ExpandEnumAsExecs = "Branches"), Category = 1)
static void multiBranch(EMultiBranchEnum1& Branches, int loopqty);
//EMultiBranchEnum1::BranchB;
};
loop1.cpp
// Fill out your copyright notice in the Description page of Project Settings.
#include "loop1.h"
void Uloop1::multiBranch(EMultiBranchEnum1& Branches, int loopqty)
{
int currloop1 = 0;
int temp = 2;
int i;
for (i = 0; i < 10; i++){
currloop1 = currloop1 + 1;
Branches = EMultiBranchEnum1::BranchA;
}
if (temp > currloop1) {
Branches = EMultiBranchEnum1::BranchB;
}
if(temp == 0) {
Branches = EMultiBranchEnum1::BranchB;
}
}
-- THE PROBLEM --
The for loop only runs the once (evident by the print node i have on branchA(It only prints a single time))
-- What should happen with the code below --
the loop should run the 10 times (my print node should print 10 times)
Instead of using UBlueprintFunctionLibrary, you should use UBlueprintAsyncActionBase. It will allow you to store state in the node and call things connected to the execution pins asynchronously.
DelayLoop.h file:
#include "CoreMinimal.h"
#include "Kismet/BlueprintAsyncActionBase.h"
#include "DelayLoop.generated.h"
DECLARE_DYNAMIC_MULTICAST_DELEGATE(FDelayOutputPin);
/**
*
*/
UCLASS()
class TEST_API UDelayLoop : public UBlueprintAsyncActionBase
{
GENERATED_UCLASS_BODY()
public:
UPROPERTY(BlueprintAssignable)
FDelayOutputPin Loop;
UPROPERTY(BlueprintAssignable)
FDelayOutputPin Complete;
UFUNCTION(BlueprintCallable,
meta = (BlueprintInternalUseOnly = "true", WorldContext = "WorldContextObject"),
Category = "Flow Control")
static UDelayLoop* DelayLoop(const UObject* WorldContextObject,
const float DelayInSeconds, const int Iterations);
virtual void Activate() override;
private:
const UObject* WorldContextObject;
float MyDelay;
int MyIterations;
bool Active;
UFUNCTION()
void ExecuteLoop();
UFUNCTION()
void ExecuteComplete();
};
DelayLoop.cpp file:
#include "DelayLoop.h"
#include "Engine/World.h"
#include "TimerManager.h"
UDelayLoop::UDelayLoop(const FObjectInitializer& ObjectInitializer) :
Super(ObjectInitializer), WorldContextObject(nullptr), MyDelay(0.0f),
MyIterations(0), Active(false)
{
}
UDelayLoop* UDelayLoop::DelayLoop(const UObject* WorldContextObject,
const float DelayInSeconds, const int Iterations)
{
UDelayLoop* Node = NewObject<UDelayLoop>();
Node->WorldContextObject = WorldContextObject;
Node->MyDelay = DelayInSeconds;
Node->MyIterations = Iterations;
return Node;
}
void UDelayLoop::Activate()
{
if (nullptr == WorldContextObject)
{
FFrame::KismetExecutionMessage(TEXT("Invalid WorldContextObject."),
ELogVerbosity::Error);
return;
}
if (Active)
{
FFrame::KismetExecutionMessage(TEXT("DelayLoop is already running."),
ELogVerbosity::Warning);
}
if (MyDelay <= 0.0f)
{
FFrame::KismetExecutionMessage(
TEXT("DelayLoop delay can't be less or equal to 0."),
ELogVerbosity::Warning);
}
if (MyIterations <= 0)
{
FFrame::KismetExecutionMessage(
TEXT("DelayLoop iterations can't be less or equal to 0."),
ELogVerbosity::Warning);
}
Active = true;
for (int i = 0; i <= MyIterations; i++)
{
FTimerHandle IterationTimer;
WorldContextObject->GetWorld()->GetTimerManager().SetTimer(
IterationTimer, this, &UDelayLoop::ExecuteLoop, MyDelay * i);
}
FTimerHandle CompleteTimer;
WorldContextObject->GetWorld()->GetTimerManager().SetTimer(
CompleteTimer, this, &UDelayLoop::ExecuteComplete,
MyDelay * (MyIterations+1));
// If the Complete pin should happen at the same time as the last iteration
// use `MyDelay * MyIterations` here instead
}
void UDelayLoop::ExecuteLoop()
{
Loop.Broadcast();
}
void UDelayLoop::ExecuteComplete()
{
Complete.Broadcast();
Active = false;
}
This will get you a blueprint that looks like this:
Note: This code is heavily based on This Creating Asynchronous Blueprint Nodes guide by Daniel ~b617 Janowski, now hosted in the legacy wiki here

How to wait for data on a COM port

I am using .Net framework's SerialPort class (System.IO.Ports) and am trying to wait to receive data. I've looked around and the WaitCommEvent function seems to be what people suggest using, however it expects a HANDLE as the first parameter. I would like to know either how to get a handle from the SerialPort or a different way to wait for data compatible with the SerialPort class.
The SerialPort class has a DataReceived event:
Indicates that data has been received through a port represented by the SerialPort object.
The documentation provides the following C++/CLI example:
#using <System.dll>
using namespace System;
using namespace System::IO::Ports;
ref class PortDataReceived
{
public:
static void Main()
{
SerialPort^ mySerialPort = gcnew SerialPort("COM1");
mySerialPort->BaudRate = 9600;
mySerialPort->Parity = Parity::None;
mySerialPort->StopBits = StopBits::One;
mySerialPort->DataBits = 8;
mySerialPort->Handshake = Handshake::None;
mySerialPort->RtsEnable = true;
mySerialPort->DataReceived += gcnew SerialDataReceivedEventHandler(DataReceivedHandler);
mySerialPort->Open();
Console::WriteLine("Press any key to continue...");
Console::WriteLine();
Console::ReadKey();
mySerialPort->Close();
}
private:
static void DataReceivedHandler(
Object^ sender,
SerialDataReceivedEventArgs^ e)
{
SerialPort^ sp = (SerialPort^)sender;
String^ indata = sp->ReadExisting();
Console::WriteLine("Data Received:");
Console::Write(indata);
}
};
int main()
{
PortDataReceived::Main();
}

Get system brightness event in windows

Can somebody will guide me how to get brightness changes event using vc++ in windows system?
or I need to get brightness slider value whenever it will change.
Any help will be very appreciated.
Thanks in advance.
A late answer but since I have been looking for the same thing. Although it is true that controlling brightness is not a Windows task but sometimes a driver's task and could also be related directly to ACPI calls, we can still get some information from Windows about its changes by implementing WMI Events. In particular, you will need to implement WmiMonitorBrightnessEvent which will give you the information you need whenever Windows receives an event of brightness change. The sample code below is a direct conversion to C++/CLI of the C# code in #RRUZ answer here where he made use of WmiMonitorBrightnessEvent.
EventWatcherAsync.h
#pragma once
using namespace System;
using namespace System::Management;
ref class EventWatcherAsync
{
public:
void WmiEventHandler(Object^ sender, EventArrivedEventArgs^ e);
EventWatcherAsync();
};
EventWatcherAsync.cpp
#include "stdafx.h"
#include "EventWatcherAsync.h"
void EventWatcherAsync::WmiEventHandler(Object^ sender, EventArrivedEventArgs^ e)
{
Console::WriteLine("Active : " + e->NewEvent->Properties["Active"]->Value->ToString());
Console::WriteLine("Brightness : " + e->NewEvent->Properties["Brightness"]->Value->ToString());
Console::WriteLine("InstanceName : " + e->NewEvent->Properties["InstanceName"]->Value->ToString());
}
EventWatcherAsync::EventWatcherAsync()
{
try
{
System::String^ ComputerName = "localhost";
System::String^ WmiQuery;
ManagementEventWatcher^ Watcher;
ManagementScope^ Scope;
if (ComputerName != "localhost")
{
ConnectionOptions^ Conn = gcnew ConnectionOptions();
Conn->Username = "";
Conn->Password = "";
Conn->Authority = "ntlmdomain:DOMAIN";
Scope = gcnew ManagementScope(String::Format("\\\\{0}\\root\\WMI", ComputerName), Conn);
}
else
Scope = gcnew ManagementScope(String::Format("\\\\{0}\\root\\WMI", ComputerName));
Scope->Connect();
WmiQuery = "Select * From WmiMonitorBrightnessEvent";
Watcher = gcnew ManagementEventWatcher(Scope, gcnew EventQuery(WmiQuery));
Watcher->EventArrived += gcnew EventArrivedEventHandler(this, &EventWatcherAsync::WmiEventHandler);
Watcher->Start();
Console::Read();
Watcher->Stop();
}
catch (Exception^ e)
{
Console::WriteLine("Exception {0} Trace {1}", e->Message, e->StackTrace);
}
}
Main.cpp
#include "stdafx.h"
#include "EventWatcherAsync.h"
using namespace System;
int main(array<System::String ^> ^args)
{
Console::WriteLine("Listening {0}", "WmiMonitorBrightnessEvent");
Console::WriteLine("Press Enter to exit");
EventWatcherAsync^ eventWatcher = gcnew EventWatcherAsync();
Console::Read();
return 0;
}

XamComboEditor SelectedItemChangedEvent firing non-stop in XamDataGrid

I have bound XamComboEditor's in two columns of XamDataGrid. When I select an item from XamComboEditor1, I would like to bind specific items to XamComboEditor2. I have attached SelectedItemChanged Event to XamComboEditor1. The event fires non-stop on selecting an item.
XAML-
<Window x:Class="WpfApplication2.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:sys="clr-namespace:System;assembly=mscorlib"
xmlns:igDP="http://infragistics.com/DataPresenter"
xmlns:igRibbon="http://infragistics.com/Ribbon"
xmlns:igOB="http://infragistics.com/OutlookBar"
xmlns:igDock="http://infragistics.com/DockManager"
xmlns:igTiles="http://infragistics.com/Tiles"
xmlns:igEditors="http://infragistics.com/Editors"
Title="Window1" Height="300" Width="720">
<Window.Resources>
</Window.Resources>
<Grid>
<DockPanel LastChildFill="True" Margin="0,26,0,-26">
<igDP:XamDataGrid x:Name="XamDataGrid1">
</igDP:XamDataGrid>
</DockPanel>
</Grid>
</Window>
Code Behind -
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using Infragistics.Windows.DataPresenter;
using Infragistics.Windows.Editors;
namespace WpfApplication2
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
EventManager.RegisterClassHandler(typeof(ValueEditor),
ValueEditor.ValueChangedEvent,
new RoutedPropertyChangedEventHandler<object>(OnValueChanged));
ComboBoxItemsProvider provider = new ComboBoxItemsProvider();
for (int i = 0; i < 6; i++)
provider.Items.Add(new ComboBoxDataItem(i, "Item " + i.ToString()));
FieldLayout fieldLayout = new FieldLayout();
UnboundField fld1 = new UnboundField();
fld1.Name = "Visibility Setting1";
Style style1 = new Style(typeof(XamComboEditor));
style1.Setters.Add(new Setter(XamComboEditor.ItemsProviderProperty, provider));
style1.Setters.Add(new EventSetter(XamComboEditor.SelectedItemChangedEvent, new RoutedPropertyChangedEventHandler<object>(XamComboEditor1_SelectedItemChanged)));
fld1.Settings.EditorStyle = style1;
fld1.Settings.EditorType = typeof(XamComboEditor);
fieldLayout.Fields.Add(fld1);
UnboundField fld2 = new UnboundField();
fld2.Name = "Visibility Setting2";
Style style2 = new Style(typeof(XamComboEditor));
fld2.Settings.EditorStyle = style2;
fld2.Settings.EditorType = typeof(XamComboEditor);
fieldLayout.Fields.Add(fld2);
this.XamDataGrid1.FieldLayouts.Add(fieldLayout);
this.XamDataGrid1.BindToSampleData = true;
}
void OnValueChanged(object sender, RoutedPropertyChangedEventArgs<object> e)
{
if (sender is XamComboEditor || sender is XamCheckEditor || sender is XamDateTimeEditor)
{
(sender as ValueEditor).EndEditMode(true, true);
if (sender is XamComboEditor)
{
XamComboEditor comboEditor = (XamComboEditor)sender;
}
}
}
private void XamComboEditor1_SelectedItemChanged(object sender, RoutedPropertyChangedEventArgs<object> e)
{
// Create combo box items provider for freight modes
ComboBoxItemsProvider provider = new ComboBoxItemsProvider();
for (int i = 0; i < 10; ++i)
{
provider.Items.Add(new ComboBoxDataItem(i.ToString(), i.ToString()));
}
//// Get unbound field associated with index
Record record = this.XamDataGrid1.ActiveRecord;
// Get the combo editor with record
UnboundField uFld = (UnboundField)record.FieldLayout.Fields[1];
// Set style for uFld
Style style = new Style(typeof(XamComboEditor));
style.Setters.Add(new Setter(XamComboEditor.ItemsProviderProperty, provider));
style.Setters.Add(new Setter(XamComboEditor.DropDownResizeModeProperty, Infragistics.Windows.Controls.PopupResizeMode.None));
style.Setters.Add(new Setter(XamComboEditor.IsAlwaysInEditModeProperty, false));
style.Setters.Add(new EventSetter(XamComboEditor.SelectedItemChangedEvent, new RoutedPropertyChangedEventHandler<object>(XamComboEditor2_SelectedItemChanged)));
style.Setters.Add(new Setter(XamComboEditor.IsEditableProperty, false));
uFld.Settings.EditorStyle = style;
uFld.Settings.EditorType = typeof(XamComboEditor);
uFld.Settings.InvalidValueBehavior = InvalidValueBehavior.RetainValue;
uFld.Settings.AllowCellVirtualization = false;
e.Handled = true;
}
private void XamComboEditor2_SelectedItemChanged(object sender, RoutedPropertyChangedEventArgs<object> e)
{
}
}
}
Shouldn't be referring back to the style in the unbound field.
Found solution at -
http://blogsprajeesh.blogspot.com/2010/03/infragistics-working-with-2.html

Creating a Windows Forms Control (C++)

trying to run this basic form control example on msdn.
At step 1 of the portion "To add a custom property to a control" we place the ClickAnywhere code in the public section of the class.
First error: "error C2144: syntax error : 'bool' should be preceded by ';'"
Is this syntax correct in C++? (see below)
(removing the ClickAnywhere portion of code, it compiles fine...)
#pragma once
using namespace System;
using namespace System::ComponentModel;
using namespace System::Collections;
using namespace System::Windows::Forms;
using namespace System::Data;
using namespace System::Drawing;
namespace clickcounter
{
/// <summary>
/// Summary for clickcounterControl
/// </summary>
///
/// WARNING: If you change the name of this class, you will need to change the
/// 'Resource File Name' property for the managed resource compiler tool
/// associated with all .resx files this class depends on. Otherwise,
/// the designers will not be able to interact properly with localized
/// resources associated with this form.
public __gc class clickcounterControl : public System::Windows::Forms::UserControl
{
public:
//Problem code*****
property bool ClickAnywhere { //Is this syntax right in C++?
bool get() {
return (label1->Dock == DockStyle::Fill);
}
void set(bool val) {
if (val)
label1->Dock = DockStyle::Fill;
else
label1->Dock = DockStyle::None;
}
}
//End Problem code*****
clickcounterControl(void)
{
InitializeComponent();
}
protected:
void Dispose(Boolean disposing)
{
if (disposing && components)
{
components->Dispose();
}
__super::Dispose(disposing);
}
private: System::Windows::Forms::Label * label1;
private:
/// <summary>
/// Required designer variable.
/// </summary>
System::ComponentModel::Container* components;
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
void InitializeComponent(void)
{
this->label1 = new System::Windows::Forms::Label();
this->SuspendLayout();
//
// label1
//
this->label1->BorderStyle = System::Windows::Forms::BorderStyle::FixedSingle;
this->label1->Location = System::Drawing::Point(32, 40);
this->label1->Name = S"label1";
this->label1->Size = System::Drawing::Size(30, 20);
this->label1->TabIndex = 0;
this->label1->Text = S"0";
this->label1->TextAlign = System::Drawing::ContentAlignment::MiddleCenter;
this->label1->Click += new System::EventHandler(this, label1_Click);
//
// clickcounterControl
//
this->Controls->Add(this->label1);
this->Name = S"clickcounterControl";
this->Size = System::Drawing::Size(100, 100);
this->ResumeLayout(false);
}
private: System::Void label1_Click(System::Object * sender, System::EventArgs * e)
{
int temp = System::Int32::Parse(label1->Text);
temp++;
label1->Text = temp.ToString();
}
};
}
Since you are using Visual Studio .Net 2003, you are using Managed C++, not C++/CLI. There is a significant difference in syntax. For a property, you must use the __property keyword, not the C++/CLI property keyword and its new style.
It should therefore be:
__property bool get_ClickAnywhere() {
return (label1->Dock == DockStyle::Fill);
}
__property void set_ClickAnywhere(bool value) {
if (value)
label1->Dock = DockStyle::Fill;
else
label1->Dock = DockStyle::None;
}
It looks like you are being tripped up by following a guide written for C++/CLI (Visual Studio 2005 and later) while still using Visual Studio 2003.