Get it on Google Play


Wm뮤 :: '윈도우폼' 카테고리의 글 목록

블로그 이미지
가끔 그림그리거나 3D모델링하거나
취미로 로봇만드는
전자과 게임프로그래머 (퇴사함)
2022.3.22f1 주로 사용
모카쨩
@Ahzkwid

Recent Comment

Archive


'윈도우폼'에 해당되는 글 14건

  1. 2025.05.30 윈폼 배포 방법 2025 (윈폼 출시 및 배포)
  2. 2025.05.23 윈폼 OCR Tesseract 사용법
  3. 2024.07.31 C# NAudio
  4. 2024.07.31 윈폼 TTS
  5. 2024.01.15 윈폼 차트
  6. 2023.09.26 윈도우용 대화형 프로그램 설정
  7. 2023.07.25 윈폼 오류 모음
  8. 2022.02.16 C# 환경변수 설정
2025. 5. 30. 11:37 윈도우폼

 

 

 

You must install .NET Desktop Runtime to run this application.
Download it now
You will need to run the downloaded installer

 

별도의 익스포트 없이 exe만 대충 던져주면 위와같은 창이 발생한다

일반이용자들은 닷넷같은거 설치 안 하기 때문

 

 



해당 폴더째로 배포하면 된다

 

 

만약 아이콘 넣으려면

이렇게 하면 된다

 

 

근데 일반사용자는 폴더내에서 exe를 찾는것이 고역이다

바깥에 바로가기를 빼놔야 하는데 바로가기는 상대경로가 안된다!

 

그래서 bat을 사용할것이다

 

텍스트 문서를 만들어서 다음과 같이 입력한다

@echo off
cd /d "%~dp0\win-x86"
start "" "Runtime.exe"

 

이것은 \win-x86\Runtime.exe를 실행하는 bat코드이다

써넣은후 확장자를 bat으로 바꿔주자

근데 bat은 아이콘이 너무 구리다

 

 

 

 

예쁘게 아이콘을 넣으려면 bat to exe를 쓴다

 

https://github.com/Makazzz/BatToExePortable

 

GitHub - Makazzz/BatToExePortable: Bat To Exe in Portableapps.com Format. Official repo here https://github.com/99fk/Bat-To-Exe-

Bat To Exe in Portableapps.com Format. Official repo here https://github.com/99fk/Bat-To-Exe-Converter-Downloader - Makazzz/BatToExePortable

github.com

 

 

 

 

 

드래그해서 넣고 아이콘 넣고 컨버트 하면 된다

 

 

 

exe는 환경에 따라 실행이 안될수도 있으므로 bat도 넣어주었다

 

근데 이거 넣으면 바이러스 검사 돌려지는게 단점이다 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

'윈도우폼' 카테고리의 다른 글

윈폼 OCR Tesseract 사용법  (0) 2025.05.23
C# NAudio  (0) 2024.07.31
윈폼 TTS  (0) 2024.07.31
posted by 모카쨩
2025. 5. 23. 10:31 윈도우폼

 

 

전에 유니티에서 OCR 돌려보는글을 썼었는데

https://wmmu.tistory.com/entry/%EC%9C%A0%EB%8B%88%ED%8B%B0-%EB%AC%B8%EC%9E%90%EC%9D%B8%EC%8B%9D

 

유니티 문자인식

https://github.com/Neelarghya/tesseract-unity GitHub - Neelarghya/tesseract-unity: Standalone OCR plugin for Unity using Tesseract Standalone OCR plugin for Unity using Tesseract. Contribute to Neelarghya/tesseract-unity development by creating an account

wmmu.tistory.com

이것과 동일한 엔진이 윈폼에도 있다

 

 

 

Nuget에서 Tesseract설치

 

그리고 아래링크에서 tessdata를 넣는다

https://github.com/tesseract-ocr/tessdata/blob/main/eng.traineddata

 

위와같이 exe 있는곳에 data를 넣어준다

폴더명도 저대로 해야함

 

 

https://gist.github.com/ahzkwid/1a039e6a8d6c293afb3cff862c0e2fcc

 

using System.Drawing;
using System.IO;
using Tesseract;

namespace AhzkwidOCRTranslatorWF
{
    internal class OCR
    {
        private TesseractEngine _engine;

        public OCR(string language = "eng", string tessdataPath = "./tessdata")
        {
            _engine = new TesseractEngine(tessdataPath, language, EngineMode.Default);
        }

        public string RecognizeText(Bitmap bitmap)
        {
            using (var pix = BitmapToPix(bitmap))
            using (var page = _engine.Process(pix))
            {
                return page.GetText();
            }
        }

        private Pix BitmapToPix(Bitmap bmp)
        {
            using (var stream = new MemoryStream())
            {
                bmp.Save(stream, System.Drawing.Imaging.ImageFormat.Bmp);
                stream.Position = 0;
                return Pix.LoadFromMemory(stream.ToArray());
            }
        }
        public Bitmap AnnotateText(Bitmap bitmap)
        {
            using (var pix = BitmapToPix(bitmap))
            using (var page = _engine.Process(pix))
            {
                var iter = page.GetIterator();
                iter.Begin();

                Bitmap annotated = new Bitmap(bitmap);
                using (Graphics g = Graphics.FromImage(annotated))
                using (Pen redPen = new Pen(Color.Red, 2))
                {
                    do
                    {
                        if (iter.TryGetBoundingBox(PageIteratorLevel.Word, out Rect rect))
                        {
                            g.DrawRectangle(redPen, rect.X1, rect.Y1, rect.Width, rect.Height);
                        }
                    }
                    while (iter.Next(PageIteratorLevel.Word));
                }

                return annotated;
            }
        }
    }
}

 

 

근데 2k넘으면 인식속도가 느려지며
3k넘으면 인식이 안되는 애매한 성능이다

 

예전엔 이거라도라는 느낌으로 썼지만 이젠 좀 불편함을 느낀다
그래서 다른거 쓰기로 함

 

'윈도우폼' 카테고리의 다른 글

윈폼 배포 방법 2025 (윈폼 출시 및 배포)  (0) 2025.05.30
C# NAudio  (0) 2024.07.31
윈폼 TTS  (0) 2024.07.31
posted by 모카쨩
2024. 7. 31. 07:15 윈도우폼

 

 

 

 

 

 

 

 

 

출력단자


for (int i = 0; i< NAudio.Wave.WaveOut.DeviceCount; i++)
{
    var caps = NAudio.Wave.WaveOut.GetCapabilities(i);
    comboBox2_Output.Items.Add(caps.ProductName);
}
if (comboBox2_Output.Items.Count > 0)
{ 
    comboBox2_Output.SelectedIndex = 0;
    outputDevice = new WaveOutEvent() { DeviceNumber = 0 };
}
void comboBox2_Output_SelectedIndexChanged(object sender, EventArgs e)
{
    outputDevice.DeviceNumber = comboBox2_Output.SelectedIndex;
}

void Speech(string str)
{
    //synth.Speak(str);




    if (outputDevice != null)
    {
        outputDevice.Stop();
    }

    var waveProvider = new SpeechToWaveProvider(synth, (string)str);
    outputDevice.Init(waveProvider);
    outputDevice.Play();



}

public class SpeechToWaveProvider : IWaveProvider
{
    private readonly BufferedWaveProvider waveProvider;

    public SpeechToWaveProvider(SpeechSynthesizer synth, string text)
    {
        var memoryStream = new MemoryStream();
        synth.SetOutputToWaveStream(memoryStream);
        synth.Speak(text);
        synth.SetOutputToDefaultAudioDevice();

        var waveFormat = new WaveFormat(22000, 1);
        waveProvider = new BufferedWaveProvider(waveFormat)
        {
            BufferLength = (int)memoryStream.Length
        };

        memoryStream.Position = 0;
        var buffer = new byte[memoryStream.Length];
        memoryStream.Read(buffer, 0, buffer.Length);
        waveProvider.AddSamples(buffer, 0, buffer.Length);
    }

    public WaveFormat WaveFormat => waveProvider.WaveFormat;

    public int Read(byte[] buffer, int offset, int count)
    {
        return waveProvider.Read(buffer, offset, count);
    }
}

 

 

 

입력단자

for (int i = 0; i < NAudio.Wave.WaveIn.DeviceCount; i++)
{
    var caps = NAudio.Wave.WaveIn.GetCapabilities(i);
    comboBox_Input.Items.Add(caps.ProductName);
}

if (comboBox_Input.Items.Count > 0)
{

    LoadRecognize();
    inputDevice = new WaveInEvent() ;
    inputDevice.DataAvailable += OnDataAvailable;
    //inputDevice.BufferMilliseconds =100;

    comboBox_Input.SelectedIndex = 0;

    //inputDevice.StartRecording();
}

private void comboBox_Input_SelectedIndexChanged(object sender, EventArgs e)
{
    inputDevice.StopRecording();
    inputDevice.DeviceNumber = comboBox_Input.SelectedIndex;
    inputDevice.StartRecording();
}
void OnDataAvailable(object s, WaveInEventArgs e)
{
    // audioStream에 데이터 추가
    if (e.Buffer.Length==0)
    {
        return;
    }

    var waveFormat = inputDevice.WaveFormat;
    var audioStreamMax = 0;
    if (audioStream.Length>0)
    {
        //audioStreamMax = audioStream.ToArray().Max();
        audioStreamMax = GetSamples(audioStream.ToArray(), waveFormat).Max();
    }

    /*
    var arr = e.Buffer;
    for (int i = 0;i< arr.Length;i++)
    {
        arr[i] = (byte)(i % 255);
    }
    audioStream.Write(arr, 0, e.BytesRecorded);

    */
    var cutout = 32;
    {

        var waveStream = new RawSourceWaveStream(new MemoryStream(e.Buffer), waveFormat) as WaveStream;
        waveViewer_Input.WaveStream = waveStream;

        if ((audioStreamMax > cutout) || (GetSamples(e.Buffer, waveFormat).Max() > cutout))
        {
            audioStream.Write(e.Buffer, 0, e.BytesRecorded);
        }
    }

    if (audioStream.Length > inputDevice.WaveFormat.SampleRate*2)
    {
        var array = audioStream.ToArray();
        var samples = GetSamples(array, waveFormat);
        var startIndex = System.Array.FindIndex(samples, x => x > cutout);
        var lastIndex = System.Array.FindLastIndex(samples, x => x > cutout);
        var length = lastIndex - startIndex + 1;
        var sliceArray = array.Skip(startIndex * 2).Take(length * 2).ToArray();


        var max = (float)samples.Max();
        var amp = 32767f / max/2;
        amp = Math.Max(1, amp);
        amp = Math.Min(16, amp);
        sliceArray = Amplify(sliceArray, amp);
        //var stream = new RawSourceWaveStream(new MemoryStream((byte[])audioStream.ToArray().Clone()), waveFormat);
        var memoryStream = new MemoryStream(sliceArray);
        var waveStream = new RawSourceWaveStream(memoryStream, waveFormat) as WaveStream;

        waveViewer_Text.WaveStream = waveStream;
        //recognizer.SetInputToAudioStream(memoryStream, new SpeechAudioFormatInfo(waveFormat.SampleRate, AudioBitsPerSample.Sixteen, AudioChannel.Stereo));

        recognizer.SetInputToAudioStream(memoryStream, new SpeechAudioFormatInfo(
            waveFormat.SampleRate,
            (AudioBitsPerSample)waveFormat.BitsPerSample,
            (AudioChannel)waveFormat.Channels
        ));

        //recognizer.SetInputToWaveStream(waveStream);
        recognizer.RecognizeAsync(RecognizeMode.Multiple);
        audioStream.SetLength(0);
        //Console.WriteLine("전달");
    }
}

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

'윈도우폼' 카테고리의 다른 글

윈폼 OCR Tesseract 사용법  (0) 2025.05.23
윈폼 TTS  (0) 2024.07.31
윈폼 차트  (0) 2024.01.15
posted by 모카쨩
2024. 7. 31. 01:06 윈도우폼

 

 

 

기본적으로 설치되어있으므로 필수는 아닌데 설치하면 좋다

 

 

 

 

 

 

 

 

 

https://github.com/ahzkwid/WindowVoice/blob/main/WindowVoice/Form1_main.cs

 

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

using System.Windows.Input;
using System.Speech.Synthesis;

namespace WindowVoice
{
    public partial class Form1_main : Form
    {
        private static SpeechSynthesizer synth = new SpeechSynthesizer();
        public Form1_main()
        {
            InitializeComponent();
            
            synth.SetOutputToDefaultAudioDevice();
            //synth.SelectVoice("Microsoft Server Speech Text to Speech Voice (ko-KR, Heami)");
            //synth.SelectVoice("Microsoft Server Speech Text to Speech Voice (ko-KR, TELE)");
            //synth.SelectVoiceByHints(VoiceGender.Male);
            //synth.SelectVoice("Microsoft Zira Desktop");
            //synth.SelectVoice("Microsoft Heami Desktop");

            textBox1_speech.KeyDown += new System.Windows.Forms.KeyEventHandler(this.key_down);
        }
        private void key_down(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Escape)//ESC눌렀을떄
            {
                textBox1_speech.Text = "";
            }
            if ((e.KeyCode == Keys.Enter || e.KeyCode == Keys.Return)) //엔터 눌렀을때
            {
                if (((Control.ModifierKeys & Keys.Alt) == Keys.Alt)) //알트눌려있을때
                {
                    int pos = textBox1_speech.SelectionStart;//텍스트박스 포인터 위치
                    textBox1_speech.Text += "\r\n"; //엔터추가 \r을 붙여야 연속추가가 되는듯
                    textBox1_speech.Select(pos + 2, 0); //텍스트박스 포인터 복구하고 엔터 길이만큼 이동
                }
                else
                {
                    e.SuppressKeyPress = true;//엔터무시
                    speech();
                    if (checkBox1_enter_to_clear.Checked == true) //엔터 누를떄 지우기 체크되어있을경우
                    {
                        textBox1_speech.Text = "";
                    }
                }
            }
        }
        private void speech()
        {
            if (textBox1_speech.Text == "문장 입력")
            {
                textBox1_speech.Text = "";
            }
            if (textBox1_speech.Text != "")
            {
                System.Threading.ThreadPool.QueueUserWorkItem(speech, textBox1_speech.Text); //스레드풀
                //speech(textBox1_speech.Text);
            }
        }
        private void speech(Object str)
        {
            synth.Speak((string)str);
        }
        private void speech(string str)
        {
            synth.Speak(str);
        }

        private void button1_enter_Click(object sender, EventArgs e)
        {
            speech();
        }
    }
}

'윈도우폼' 카테고리의 다른 글

C# NAudio  (0) 2024.07.31
윈폼 차트  (0) 2024.01.15
윈도우용 대화형 프로그램 설정  (0) 2023.09.26
posted by 모카쨩
2024. 1. 15. 22:58 윈도우폼

 

 

 

 

 

 

system.windows.forms.datavisualization

을 쳐서 설치

 

 

 

 

 

그리고 왠지 Form1이 이런 에러 뜨면서 닫혔다

 

 

 

업데이트 하면 고쳐진다

 

 

 

 

 

 

 

 

 

 

 

 

설치 끝

 

 

아래는 내가 자주 쓰는 차트 코드들이다

 

 

 

마우스 댄 곳의 차트값 표시

 

V1

V1은 특정 차트만 사용한다

더보기
private void chart1_MouseMove(object sender, MouseEventArgs e)
{
    DrawChartValue(chart1, e);
}
private void chart2_MouseMove(object sender, MouseEventArgs e)
{
    DrawChartValue(chart2, e);
}
private void chart3_MouseMove(object sender, MouseEventArgs e)
{
    DrawChartValue(chart3,e);
}

DataPoint prePoint = null;
ToolTip tooltip = new ToolTip();
private void DrawChartValue(Chart chart, MouseEventArgs e)
{
    HitTestResult result = chart.HitTest(e.X, e.Y);
    if (result.PointIndex < 0)
    {
        return;
    }
    if (chart.Series.Count==0)
    {
        return;
    }
    if (result.PointIndex >= chart.Series[0].Points.Count)
    {
        return;
    }
    {
        var dataPoint = chart.Series[0].Points[result.PointIndex];
        var date = DateTime.FromOADate(dataPoint.XValue);
        var value = dataPoint.YValues[0];

        var text = $"Date: {date.ToShortDateString()}\nValue: {value.ToString("F2")}";
        if (tooltip.GetToolTip(chart) != text)
        {
            tooltip.AutoPopDelay = 60*1000; //60초
            tooltip.SetToolTip(chart, text);
        }
        if (prePoint != dataPoint)
        {
            if (prePoint != null)
            {
                prePoint.MarkerStyle = MarkerStyle.None;
            }
            prePoint = dataPoint;
            dataPoint.MarkerStyle = MarkerStyle.Circle;
            dataPoint.MarkerSize = 8;
            dataPoint.MarkerColor = System.Drawing.Color.Red;
        }
    }
}

 

V2 모든 차트 사용

더보기
private void chart1_MouseMove(object sender, MouseEventArgs e)
{
    DrawChartValue(chart1, e);
}
private void chart2_MouseMove(object sender, MouseEventArgs e)
{
    DrawChartValue(chart2, e);
}
private void chart3_MouseMove(object sender, MouseEventArgs e)
{
    DrawChartValue(chart3,e);
}

DataPoint prePoint = null;
ToolTip tooltip = new ToolTip();
private void DrawChartValue(Chart chart, MouseEventArgs e)
{
    if (chart.Series.Count == 0)
    {
        return;
    }
    var result = chart.HitTest(e.X, e.Y);
    //var result = HitTestX(chart,e);
    if (result.PointIndex < 0)
    {
        return;
    }
    if (result.Series==null)
    {
        return;
    }
    if (result.PointIndex >= result.Series.Points.Count)
    {
        return;
    }
    {
        var dataPoint = result.Series.Points[result.PointIndex];
        var date = DateTime.FromOADate(dataPoint.XValue);
        var value = dataPoint.YValues[0];

        var text = $"{result.Series.Name}\nDate: {date.ToShortDateString()}\nValue: {value.ToString("F2")}";
        if (tooltip.GetToolTip(chart) != text)
        {
            tooltip.AutoPopDelay = 60*1000; //60초
            tooltip.SetToolTip(chart, text);
        }
        if (prePoint != dataPoint)
        {
            if (prePoint != null)
            {
                prePoint.MarkerStyle = MarkerStyle.None;
            }
            prePoint = dataPoint;
            dataPoint.MarkerStyle = MarkerStyle.Circle;
            dataPoint.MarkerSize = 8;
            dataPoint.MarkerColor = System.Drawing.Color.Red;
        }
    }
}

 

 

 

V3

가로축만 사용하는 검색기를 만들었다

근데 만들고보니까 V1보단 낫지만 V2가 더 유용한듯

더보기
private void chart1_MouseMove(object sender, MouseEventArgs e)
{
    DrawChartValue(chart1, e);
}
private void chart2_MouseMove(object sender, MouseEventArgs e)
{
    DrawChartValue(chart2, e);
}
private void chart3_MouseMove(object sender, MouseEventArgs e)
{
    DrawChartValue(chart3,e);
}

DataPoint prePoint = null;
ToolTip tooltip = new ToolTip();
private void DrawChartValue(Chart chart, MouseEventArgs e)
{
    if (chart.Series.Count == 0)
    {
        return;
    }
    //var result = chart.HitTest(e.X, e.Y);
    var result = HitTestX(chart,e);
    if (result.PointIndex < 0)
    {
        return;
    }
    if (result.Series==null)
    {
        return;
    }
    if (result.PointIndex >= result.Series.Points.Count)
    {
        return;
    }
    {
        var dataPoint = result.Series.Points[result.PointIndex];
        var date = DateTime.FromOADate(dataPoint.XValue);
        var value = dataPoint.YValues[0];

        var text = $"{result.Series.Name}\nDate: {date.ToShortDateString()}\nValue: {value.ToString("F2")}";
        if (tooltip.GetToolTip(chart) != text)
        {
            tooltip.AutoPopDelay = 60*1000; //60초
            tooltip.SetToolTip(chart, text);
        }
        if (prePoint != dataPoint)
        {
            if (prePoint != null)
            {
                prePoint.MarkerStyle = MarkerStyle.None;
            }
            prePoint = dataPoint;
            dataPoint.MarkerStyle = MarkerStyle.Circle;
            dataPoint.MarkerSize = 8;
            dataPoint.MarkerColor = System.Drawing.Color.Red;
        }
    }
}
public static HitTestResult HitTestX(Chart chart, MouseEventArgs e)
{
    var hitTestResult = new HitTestResult();

    var chartArea = chart.ChartAreas[0];
    chartArea.CursorX.SetCursorPixelPosition(new Point(e.X, e.Y), true);
    var result = chart.HitTest(e.X, e.Y);
    if (result.ChartArea == null)
    {
        return hitTestResult;
    }
    var xValue = chartArea.AxisX.PixelPositionToValue(e.X);

    foreach (var series in chart.Series)
    {
        for (int i = 1; i < series.Points.Count; i++)
        {
            if ((series.Points[i-1].XValue + series.Points[i].XValue) / 2 < xValue)
            {
                continue;
            }
            hitTestResult.Series = series;
            hitTestResult.PointIndex = i-1;
            return hitTestResult;
        }
    }

    return hitTestResult;
}

 

 

 

V4

V2를 더욱 개량하여  단일 함수, 단일인자로 통합시킴

prams가 들어가서 필요하다면 V2에 쓰이던 시스템과 호환도 가능하다

https://gist.github.com/ahzkwid/6b5502e408914dac8fd5b5668489a73f

 

WindowsForms/DrawChartValue

WindowsForms/DrawChartValue. GitHub Gist: instantly share code, notes, and snippets.

gist.github.com

 

public Form1()
{
    InitializeComponent();

    foreach (var chart in Charts)
    {
        chart.MouseMove += charts_MouseMove;
    }
}

private void charts_MouseMove(object sender, MouseEventArgs e)
{
    DrawChartValue(Charts);
}
Chart[] Charts
{
    get
    {
        return new Chart[] { chart1, chart2, chart3 };
    }
}
DataPoint prePoint = null;
ToolTip tooltip = new ToolTip();
private void DrawChartValue(params Chart[] charts)
{

    Chart chartMain = null;
    var mousePosition = Point.Empty;
    foreach (var chart in charts)
    {
        mousePosition = chart.PointToClient(MousePosition);
        if (chart.ClientRectangle.Contains(mousePosition))
        {
            //차트 내부인지 검사절차를 거치지 않으면 다른 이벤트와 충돌 가능성이 있다
            chartMain = chart;
            break;
        }
    }
    if (chartMain == null)
    {
        return;
    }

    {
        var chart = chartMain;



        if (chart.Series.Count == 0)
        {
            return;
        }


        var result = chart.HitTest(mousePosition.X, mousePosition.Y);
        //var result = HitTestX(chart,e);
        if (result.PointIndex < 0)
        {
            return;
        }
        if (result.Series == null)
        {
            return;
        }
        if (result.PointIndex >= result.Series.Points.Count)
        {
            return;
        }
        {
            var dataPoint = result.Series.Points[result.PointIndex];
            var date = DateTime.FromOADate(dataPoint.XValue);
            var value = dataPoint.YValues[0];

            var text = $"{result.Series.Name}\nDate: {date.ToShortDateString()}\nValue: {value.ToString("F2")}";
            if (tooltip.GetToolTip(chart) != text)
            {
                tooltip.AutoPopDelay = 60 * 1000; //60초
                tooltip.SetToolTip(chart, text);
            }
            if (prePoint != dataPoint)
            {
                if (prePoint != null)
                {
                    prePoint.MarkerStyle = MarkerStyle.None;
                }
                prePoint = dataPoint;
                dataPoint.MarkerStyle = MarkerStyle.Circle;
                dataPoint.MarkerSize = 8;
                dataPoint.MarkerColor = System.Drawing.Color.Red;
            }
        }
    }
}

 

 

 

 

 

차트 XY커서 표시

https://gist.github.com/ahzkwid/10152f22ad3a05879a90ebe0367b6b49

 

WindowsForms/DrawCursors

WindowsForms/DrawCursors. GitHub Gist: instantly share code, notes, and snippets.

gist.github.com

 

public Form1()
{
    InitializeComponent();

    chart1.MouseMove += charts_MouseMove;
}
private void charts_MouseMove(object sender, MouseEventArgs e)
{
    DrawCursors(Charts);
}
Chart[] Charts
{
    get
    {
        return new Chart[] { chart1, chart2, chart3 };
    }
}
void DrawCursors(params Chart[] charts)
{
    Chart chartMain = null;
    var mousePosition = Point.Empty;
    foreach (var chart in charts)
    {
        mousePosition = chart.PointToClient(MousePosition);
        if (chart.ClientRectangle.Contains(mousePosition))
        {
            //차트 내부인지 검사절차를 거치지 않으면 다른 이벤트와 충돌 가능성이 있다
            chartMain = chart;
            break;
        }
    }
    if (chartMain == null)
    {
        return;
    }

    {
        var chart = chartMain;
        var result = chart.HitTest(mousePosition.X, mousePosition.Y);
        if (result.ChartArea == null)
        {
            return;
        }
    }


    //X커서 표시(실수)
    {
        var chart = chartMain;
        var x = mousePosition.X;
        x = Math.Min(x, chart.Width - 20);
        x = Math.Max(0, x);
        double xValue = chart.ChartAreas[0].AxisX.PixelPositionToValue(x);
        chart.ChartAreas[0].CursorX.Position = xValue;
    }



    //Y커서 표시(실수)
    {
        var chart = chartMain;
        var y = mousePosition.Y;
        y = Math.Min(y, chart.Height - 20);
        y = Math.Max(0, y);
        double yValue = chart.ChartAreas[0].AxisY.PixelPositionToValue(y);
        chart.ChartAreas[0].CursorY.Position = yValue;

    }


    var xPosition = chartMain.ChartAreas[0].CursorX.Position;
    //X커서 복제
    foreach (var chart in Charts)
    {
        chart.ChartAreas[0].CursorX.Position = xPosition;
    }
}

 

 

 

'윈도우폼' 카테고리의 다른 글

윈폼 TTS  (0) 2024.07.31
윈도우용 대화형 프로그램 설정  (0) 2023.09.26
윈폼 오류 모음  (0) 2023.07.25
posted by 모카쨩
2023. 9. 26. 13:42 윈도우폼

네이버카페에 썼던 16년글 이전

 

Properties에서

FormBorderStyle을 None로 설정
BackgroundImageLayout를 Center로 설정
Size를 0,0으로 설정 //윈도우에서는 최소 윈도우 크기가 한정되어 있다
Location을 -100,-100으로 설정
StartPosition을 Manual로 설정

ShowIcon을 False로 설정

ShowInTaskbar를 False로 설정
 
 
 
다음과 같이 변수를 초기화 한다
 
        입력창 입력창변수;
 
생성자에 다음과 같이 써 넣는다

            this.TransparencyKey = BackColor;

            //SetStyle(ControlStyles.SupportsTransparentBackColor, true);
 
            //컨트롤명.BackColor = Color.Transparent;
 
            //this.TransparencyKey = System.Drawing.Color.FromArgb(0x78F0F0F0);
//투명컨트롤이 필요할경우(호환 비보장)
 
//CheckForIllegalCrossThreadCalls = false; 크로스 스레드 사용시
 
            this.BackgroundImage = new Bitmap("사진 파일 위치, 240*240이상 권장");
 
            this.Width = BackgroundImage.Width;
            this.Height = BackgroundImage.Height;
 
            this.Location = new Point(Screen.PrimaryScreen.Bounds.Width - this.Width, Screen.PrimaryScreen.Bounds.Height - this.Height);
//맨 윗줄에 넣을것
 
            this.MouseDown += new System.Windows.Forms.MouseEventHandler(this.mouse_down);
 
 
 
 
 
 
 
 
//다음과 같은 이벤트를 추가한다
        private void mouse_down(object sender, MouseEventArgs e)
        {
            if ((입력창변수== null) || ((입력창변수.IsDisposed)))
            {
                입력창변수= new 입력창();
            }
            if (입력창변수 != null)
            {
                입력창변수.Show();
                입력창변수.Enabled = true;
            }
        }
 
 
 
 
 
다른창에서 AI를 호출할경우
if(this.Enabled == false)
{
this.Opacity=0.5;
this.TopMost=true;
}

'윈도우폼' 카테고리의 다른 글

윈폼 차트  (0) 2024.01.15
윈폼 오류 모음  (0) 2023.07.25
C# 환경변수 설정  (0) 2022.02.16
posted by 모카쨩
2023. 7. 25. 09:18 윈도우폼

 

 

 

------------------------------------------------------------------------------------------------------------------------------

모든 차트 영역 요소의 위치를 계산하기 전에는 PositionToValue 메서드를 호출할 수 없습니다

PositionToValue method cannot be called prior to calculating position of all chart area elements.

 

 

MouseMove 이벤트중에 PixelPositionToValue를 호출해서 발생했는데

아래와 같이 HitTest를 먼저 진행해서 하면 해결된다

var result = chart.HitTest(e.X, e.Y);
if (result.ChartArea != null)
{
    var xValue = chartArea.AxisX.PixelPositionToValue(e.X);
}

 

 

 

------------------------------------------------------------------------------------------------------------------------------

System.ArgumentException: '이름이 '차트이름'인 차트 요소를 'SeriesCollection'에서 찾을 수 없습니다.'

chart.ChartAreas[0].CursorX.SetCursorPixelPosition(mousePosition, true);

할때 발생했는데 이거도 역시 이벤트 충돌로 인해 발생한 결과로 다음과 같이 수정했다

//X커서 표시(실수)
{
    var x = mousePosition.X;
    x = Math.Max(0, x);
    x = Math.Min(x, chart.Width);
    double xValue = chart.ChartAreas[0].AxisX.PixelPositionToValue(x);
    chart.ChartAreas[0].CursorX.Position = xValue;
    position = chart.ChartAreas[0].CursorX.Position;
}

 

 

 

 

 

 

 


------------------------------------------------------------------------------------------------------------------------------

 

System.ArgumentException: 'Not a legal OleAut date.'

var dataPoint = result.Series.Points[result.PointIndex];
var date = DateTime.FromOADate(dataPoint.XValue);

 

https://stackoverflow.com/questions/310700/meaning-of-exception-in-c-sharp-app-not-a-legal-oleaut-date

 

화면에서 포인터를 가져와서 사용할경우 간헐적으로 값이 오류나면서 생기는 버그인데

범위지정을 다 할 필요는 없고

var dataPoint = result.Series.Points[result.PointIndex];
if (dataPoint.XValue >= 2958465) 
{
    return;
}
var date = DateTime.FromOADate(dataPoint.XValue);

 

이렇게 고치면 된다

 

 

 

'윈도우폼' 카테고리의 다른 글

윈도우용 대화형 프로그램 설정  (0) 2023.09.26
C# 환경변수 설정  (0) 2022.02.16
잘 안 쓰는 윈폼코드 모음  (0) 2021.07.19
posted by 모카쨩
2022. 2. 16. 15:12

보호되어 있는 글입니다.
내용을 보시려면 비밀번호를 입력하세요.


저사양 유저용 블로그 진입