NewsTicker: custom control in Visual C++

Discussion in 'Mixed Languages' started by Jachra, Oct 3, 2019.

  1. Jachra

    Jachra MDL Member

    Apr 5, 2010
    184
    55
    10
    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"
    
     
  2. Michaela Joy

    Michaela Joy MDL Crazy Lady

    Jul 26, 2012
    3,947
    4,419
    120
    Perhaps I'm missing something, but I don't see a timer tick event handler.
     
    Stop hovering to collapse... Click to collapse... Hover to expand... Click to expand...
  3. Jachra

    Jachra MDL Member

    Apr 5, 2010
    184
    55
    10
  4. Michaela Joy

    Michaela Joy MDL Crazy Lady

    Jul 26, 2012
    3,947
    4,419
    120
    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();
     
    Stop hovering to collapse... Click to collapse... Hover to expand... Click to expand...
  5. Jachra

    Jachra MDL Member

    Apr 5, 2010
    184
    55
    10
    That doesn't work. What else can I do?
     
  6. Michaela Joy

    Michaela Joy MDL Crazy Lady

    Jul 26, 2012
    3,947
    4,419
    120
    @Jachra: Time to debug the code. Set a breakpoint on the timer tick and see if it's getting called.
     
    Stop hovering to collapse... Click to collapse... Hover to expand... Click to expand...
  7. Jachra

    Jachra MDL Member

    Apr 5, 2010
    184
    55
    10
    @Michaela Joy, your help set me in the right direction and I thank you for your help. :)