I tried to make a custom control in Visual C++ for a NewsTicker. I translate the source code that is on CodeProject from Graham Lemon. It compiles, but it doesn't work. I do not know what I did wrong? Can someone check and tell me what I need to change? I also would like that this wouldn't be a separate dll, but can be embedded straight in the executable. And I came up with the following code: This is the Newsticker.h: Code: #pragma once #using <mscorlib.dll> //#using <Microsoft.VisualBasic.dll> using namespace System::Windows::Forms; using namespace System::Drawing; using namespace System::Drawing::Drawing2D; using namespace System::ComponentModel; //using namespace Microsoft::VisualBasic; #include <string> #include "floating_point_to_integer.h" using namespace System; using namespace System::ComponentModel; using namespace System::Collections; using namespace System::Diagnostics; namespace NewsTicker { /// <summary> /// Summary for MyNewsTicker /// </summary> public ref class MyNewsTicker : public System::Windows::Forms::UserControl { #pragma region Constants #pragma endregion #pragma region Enumerations private: enum class TextPlacement { Top, Middle, Bottom }; #pragma endregion #pragma region Variables private: float X = 0; float Y = 0; Graphics ^Gr; public: TextPlacement _tpos = TextPlacement::Top; public: String^ _news = L"There is nothing to display at this time"; public: SizeF _strSize; public: System::Windows::Forms::Timer^ Timer; public: System::Windows::Forms::Label^ label1; private: private: double _speed = 1.0; #pragma endregion public: /*virtual ~MyNewsTicker() { delete Gr; }*/ private: void MyNewsTicker::MyNewsTicker_Load(System::Object^ sender, System::EventArgs^ e) { SetupWindow(); } void MyNewsTicker::MyNewsTicker_Resize(System::Object^ sender, System::EventArgs^ e) { SetupWindow(); } void MyNewsTicker::Timer_Tick(System::Object^ sender, System::EventArgs^ e) { UpdateDisplay(); } void MyNewsTicker::MyNewsTicker_hover(System::Object^ sender, System::EventArgs^ e) { Timer->Stop(); } void MyNewsTicker::MyNewsTicker_leave(System::Object^ sender, System::EventArgs^ e) { Timer->Start(); } void MyNewsTicker::SetupWindow() { this->SetStyle(ControlStyles::OptimizedDoubleBuffer, true); label1->Height = this->Height - 4; label1->Text = _news; label1->AutoSize = true; label1->Location = Point(this->Width, 0); this->Dock = DockStyle::Bottom; this->BorderStyle = Windows::Forms::BorderStyle::Fixed3D; X = static_cast<int>(this->Width); if ((this->Height < (label1->Height + 4))) { this->Height = (static_cast<int>(label1->Height) + 4); } Timer->Interval = 25; Timer->Start(); } void MyNewsTicker::UpdateDisplay() { double tHeight = label1->Height; switch (this->getTextPosition()) { case TextPlacement::Top: { Y = 0; break; } case TextPlacement::Middle: { Y = static_cast<float>(((this->Height / 2) - (tHeight / static_cast<double>(2)))); break; } case TextPlacement::Bottom: { Y = static_cast<float>((this->Height - tHeight)); break; } } label1->Location = Point(FloatingPointToInteger::ToInt32(X), FloatingPointToInteger::ToInt32(Y)); if (X <= (0 - label1->Width)) { X = this->Width; } else { X = static_cast<float>((static_cast<double>(X)-_speed)); } } /// <summary> /// Set the text to display in the ticker /// </summary> /// <value></value> /// <returns></returns> /// <remarks></remarks> public: String^ MyNewsTicker::getNews() { return _news; } void MyNewsTicker::setNews(String^ value) { _news = value; // Need to reset the control with the new text SetupWindow(); } /// <summary> /// Define the location of the text in the ticker /// </summary> /// <value></value> /// <returns></returns> /// <remarks></remarks> MyNewsTicker::TextPlacement MyNewsTicker::getTextPosition() { return _tpos; } void MyNewsTicker::setTextPosition(TextPlacement value) { _tpos = value; } /// <summary> /// Set the scrolling speed for the ticker /// </summary> /// <value></value> /// <returns></returns> /// <remarks></remarks> double MyNewsTicker::getSpeed() { return _speed; } void MyNewsTicker::setSpeed(double value) { if ((value < 0.01) | (value > static_cast<double>(100))) { throw gcnew System::ArgumentOutOfRangeException(L"Speed", L"Cannot be less than 0.01 or greater than 100"); } else { _speed = value; SetupWindow(); } } public: MyNewsTicker(void) { InitializeComponent(); // //TODO: Add the constructor code here // } MyNewsTicker(System::ComponentModel::IContainer ^container) { /// <summary> /// Required for Windows.Forms Class Composition Designer support /// </summary> container->Add(this); InitializeComponent(); } protected: /// <summary> /// Clean up any resources being used. /// </summary> ~MyNewsTicker() { if (components) { delete components; } delete Gr; } public: System::Windows::Forms::UserControl^ NewsTicker; protected: protected: private: System::ComponentModel::IContainer^ components; protected: private: /// <summary> /// Required designer variable. /// </summary> #pragma region Windows Form Designer generated code /// <summary> /// Required method for Designer support - do not modify /// the contents of this method with the code editor. /// </summary> void InitializeComponent(void) { this->components = (gcnew System::ComponentModel::Container()); this->NewsTicker = (gcnew System::Windows::Forms::UserControl()); this->Timer = (gcnew System::Windows::Forms::Timer(this->components)); this->label1 = (gcnew System::Windows::Forms::Label()); this->SuspendLayout(); // // NewsTicker // this->NewsTicker->AutoSize = true; this->NewsTicker->BackColor = System::Drawing::SystemColors::Info; this->NewsTicker->Font = (gcnew System::Drawing::Font(L"Tahoma", 8.25F)); this->NewsTicker->Location = System::Drawing::Point(0, 0); this->NewsTicker->Margin = System::Windows::Forms::Padding(4, 5, 4, 5); this->NewsTicker->Name = L"NewsTicker"; this->NewsTicker->Size = System::Drawing::Size(434, 31); this->NewsTicker->TabIndex = 0; // // label1 // this->label1->AutoSize = true; this->label1->Location = System::Drawing::Point(0, 10); this->label1->Margin = System::Windows::Forms::Padding(4, 0, 4, 0); this->label1->Name = L"label1"; this->label1->Size = System::Drawing::Size(116, 13); this->label1->TabIndex = 0; this->label1->Text = L"No News is Good News"; this->label1->TextAlign = System::Drawing::ContentAlignment::MiddleCenter; // // MyNewsTicker // this->AutoScaleDimensions = System::Drawing::SizeF(6, 13); this->AutoScaleMode = System::Windows::Forms::AutoScaleMode::Font; this->AutoSize = true; this->BackColor = System::Drawing::Color::Transparent; this->Controls->Add(this->label1); this->DoubleBuffered = true; this->Font = (gcnew System::Drawing::Font(L"Tahoma", 8.25F)); this->Margin = System::Windows::Forms::Padding(4, 5, 4, 5); this->Name = L"MyNewsTicker"; this->Size = System::Drawing::Size(434, 33); this->ResumeLayout(false); this->PerformLayout(); } #pragma endregion }; } This is the floating_point_to_integer.h: Code: #include <cmath> class FloatingPointToInteger { public: static char ToSByte(double source) { char floor = (char)std::floor(source); if (std::abs(source - floor) == 0.5) { if (floor % 2 == 0) return floor; else return (char)std::ceil(source); } else if (std::abs(source - floor) < 0.5) return floor; else return (char)std::ceil(source); } static unsigned char ToByte(double source) { unsigned char floor = (unsigned char)std::floor(source); if (std::abs(source - floor) == 0.5) { if (floor % 2 == 0) return floor; else return (unsigned char)std::ceil(source); } else if (std::abs(source - floor) < 0.5) return floor; else return (unsigned char)std::ceil(source); } static short ToInt16(double source) { short floor = (short)std::floor(source); if (std::abs(source - floor) == 0.5) { if (floor % 2 == 0) return floor; else return (short)std::ceil(source); } else if (std::abs(source - floor) < 0.5) return floor; else return (short)std::ceil(source); } static unsigned short ToUInt16(double source) { unsigned short floor = (unsigned short)std::floor(source); if (std::abs(source - floor) == 0.5) { if (floor % 2 == 0) return floor; else return (unsigned short)std::ceil(source); } else if (std::abs(source - floor) < 0.5) return floor; else return (unsigned short)std::ceil(source); } static int ToInt32(double source) { int floor = (int)std::floor(source); if (std::abs(source - floor) == 0.5) { if (floor % 2 == 0) return floor; else return (int)std::ceil(source); } else if (std::abs(source - floor) < 0.5) return floor; else return (int)std::ceil(source); } static unsigned int ToUInt32(double source) { unsigned int floor = (unsigned int)std::floor(source); if (std::abs(source - floor) == 0.5) { if (floor % 2 == 0) return floor; else return (unsigned int)std::ceil(source); } else if (std::abs(source - floor) < 0.5) return floor; else return (unsigned int)std::ceil(source); } static long long ToInt64(double source) { long long floor = (long long)std::floor(source); if (std::abs(source - floor) == 0.5) { if (floor % 2 == 0) return floor; else return (long long)std::ceil(source); } else if (std::abs(source - floor) < 0.5) return floor; else return (long long)std::ceil(source); } static unsigned long long ToUInt64(double source) { unsigned long long floor = (unsigned long long)std::floor(source); if (std::abs(source - floor) == 0.5) { if (floor % 2 == 0) return floor; else return (unsigned long long)std::ceil(source); } else if (std::abs(source - floor) < 0.5) return floor; else return (unsigned long long)std::ceil(source); } }; This is the MyNewsTicker.cpp: Code: #include "stdafx.h" #include "MyNewsTicker.h"
That is in: void MyNewsTicker::Timer_Tick(System::Object^ sender, System::EventArgs^ e) { UpdateDisplay(); } Or do you mean something like: myTimer->Tick += gcnew EventHandler( TimerEventProcessor ); Link: https://docs.microsoft.com/en-us/dotnet/api/system.windows.forms.timer.tick?view=netframework-4.8
I think you can do this... Code: void InitializeComponent(void) { this->components = (gcnew System::ComponentModel::Container()); this->NewsTicker = (gcnew System::Windows::Forms::UserControl()); this->Timer = (gcnew System::Windows::Forms::Timer(this->components)); this->Timer->Tick += gcnew EventHandler( Timer_Tick ); If it complains about not being able to see the timer_tick procedure, then move it directly after the call to InitializeComponent();