X, Y 좌표값을 얻기 위해 만든 Form

 

타이머는 System.Windows.Forms.Timer 를 사용했습니다.

 

체크박스에 체크를 하면 timer가 동작되고 

스페이스바 키를 눌렀을때

체크박스의 체크가 해제되면서

timer가 정지됩니다.

 

체크를 하면 X, Y 좌표값을 실시간으로 가져온다.

 

public partial class Form1 : Form
    {
        [DllImport("user32.dll")]
        static extern void mouse_event(uint dwFlags, uint dx, uint dy, uint dwData, int dwExtraInfo);

        private const uint MOUSEEVENTF_LEFTDOWN = 0x0000; //= 0x0002;      // The left button is down.
        private const uint MOUSEEVENTF_LEFTUP = 0x0000;// = 0x0004;        // The left button is up.

        public Form1()
        {
            InitializeComponent();
        }

        private void timer1_Tick(object sender, EventArgs e)
        {
            lbX1.Text = Cursor.Position.X.ToString();
            lbY1.Text = Cursor.Position.Y.ToString();
        }

        private void btnStop1_Click(object sender, EventArgs e)
        {
            timer1.Stop();
        }

        private void Form1_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Space)
            {
                if (cbP1.Checked)
                {
                    btnStop1.PerformClick();
                    cbP1.Checked = false;
                }
            }
        }

        private void cbP1_CheckedChanged(object sender, EventArgs e)
        {
            if(cbP1.Checked)
            {
                timer1.Start();
                this.ActiveControl = null;

            }
        }

 

윈폼으로 개발하다가 간혹 Key_Down 이벤트가 작동하지 않을때가 있다.
키보드 메시지를 다른 컨트롤이 먼저 받아서 처리해버려서 
폼의 이벤트 핸들러는 해당 메시지를 받지 못하기 때문이다.
이런 경우 KeyPreview 속성을 true로 설정함으로써, 해당 폼의 이벤트 핸들러가 해당 메시지를 먼저 
처리하도록해서 해결할 수 있다.

 

this.KeyPreview = true;

 

 

 

CheckForIllegalCrossThreadCalls = false;

 

어디까지나 임시방편 


결국에는 invoke 또는  BackgroundWorker를 사용해서 수정해야함.

오픈소스 사용함

 

URL: https://github.com/Enichan/Ini

 

GitHub - Enichan/Ini: Ini file reader/writer for C# / .NET written in pure .NET in a single source file

Ini file reader/writer for C# / .NET written in pure .NET in a single source file - GitHub - Enichan/Ini: Ini file reader/writer for C# / .NET written in pure .NET in a single source file

github.com

 

 

Ini.cs
0.03MB

 

Kernel32를 사용하지 않고 cs파일 하나만 추가해서 매우 간단하고 직관적으로 코딩할수 있다.

 

 

            // ini 쓰기
            IniFile ini = new IniFile();
            ini["Setting"]["USE_FLAG"] = "true";
            ini["Setting"]["Delay_Time"] = "10";
            ini["INPUT_DATA"]["TEXT1"] = "DATA1";
            ini.Save("C:\\Setting.ini");
 
            // ini 읽기
            ini.Load("C:\\Setting.ini");
            string useflag = ini["Setting"]["USE_FLAG"].ToString();
            string delay_time = ini["Setting"]["Delay_Time"].ToString();
            string textdata1 = ini["INPUT_DATA"]["TEXT1"].ToString();

 

진짜 많이 검색해보고 나름대로 가장 심플하면서 확실한 방법을 찾은거같아서 글을 작성합니다.

 

그냥 Excel.EXE 프로세스를 죽이게 되면 다른 실행되있는 엑셀파일도 전부 날아가기때문에

 

엑셀의 PID(Process ID)를 획득 후 해당 ID에 대해서만 Kill하게 됩니다.

 

예제)

    class Program
    {
        [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        static extern uint GetWindowThreadProcessId(IntPtr hWnd, out uint lpdwProcessId);

        static void Main(string[] args)
        {
            Microsoft.Office.Interop.Excel.Application excel = null;
            Workbook workbook = null;
            Worksheet worksheet = null;
            uint processId = 0;

            excel = new Microsoft.Office.Interop.Excel.Application();
            // 엑셀 내용 Start
                      º
                      º
                      º  
                      º
                      º
            // 엑셀 내용 End
            
            GetWindowThreadProcessId(new IntPtr(excel.Hwnd), out processId); //PID 획득
            workbook .Save();       
            workbook.Close(Type.Missing, Type.Missing, Type.Missing);     
            excel.Quit();

            if (processId != 0)
            {
                System.Diagnostics.Process excelProcess = System.Diagnostics.Process.GetProcessById((int)processId);
                excelProcess.CloseMainWindow();
                excelProcess.Refresh();
                excelProcess.Kill();
            }
        }
    }

 

'Programing > C#' 카테고리의 다른 글

C# 디버깅시 Cross Thread 임시 해결방법  (0) 2022.05.09
C# ini 파일 읽기 쓰기  (0) 2022.04.22
C# Excel 프로세스 해제  (0) 2022.03.12
C# LOG파일 생성  (0) 2022.03.12
C# CrossThread Error 해결  (0) 2022.02.21

COM 객체와 닷넷의 가바지 컬렉션이 궁합이 맞지않아 프로세스가 종료되지 않는 현상이 자주 발생한다.

 

엑셀COM 프로세스가 종료되려면 Application, WorkBook, WorkSheet 등이 해제(release)되어야된다.

 

       
        Microsoft.Office.Interop.Excel.Workbook pWorkbook = null;
        Microsoft.Office.Interop.Excel.Sheets pWorkSheets = null;
        Microsoft.Office.Interop.Excel.Worksheet pWorkSheet = null;
       
        m_ExcelApp = new Microsoft.Office.Interop.Excel.ApplicationClass();

        // 엑셀 내용 Start
                      º
                      º
                      º  
                      º
                      º
        // 엑셀 내용 End
        
        pWorkbook.Save();

        releaseObject(m_ExcelApp);
        releaseObject(pWorkSheet);
        releaseObject(pWorkSheets);
        releaseObject(pWorkbook);

        System.GC.Collect();
        System.GC.WaitForPendingFinalizers();


        private static void releaseObject(object obj)
        {
            try
            {
                System.Runtime.InteropServices.Marshal.ReleaseComObject(obj);
                obj = null;
            }
            catch (Exception e)
            {
                obj = null;
            }
            finally
            {
                GC.Collect();
            }
        }


 

만약 Release 했는데도 EXCEL.EXE가 프로세스에 남아있다면 PID를 찾아 프로세스를 kill해주면 된다.

다음글에 작성...

업무중에 갑자기 LOG를 찍어봐야할때 간단하게 txt파일로 만들어 확인할 수 있는 코드 

 

            string Fpath = @"C:\temp\새폴더\LOG.txt"; // 파일 경로 
            DirectoryInfo dif = new DirectoryInfo(@"C:\temp\새폴더"); // 디렉토리 경로

            if (!dif.Exists) // 디렉토리 체크
            {
                dif.Create();
            }

            FileInfo file = new FileInfo(Fpath); // 파일 체크 후 생성
            if (!file.Exists)
            {
                FileStream fs = file.Create();
                fs.Close();
            }

            File.AppendAllText(Fpath, "LOG 메세지");   // 시간추가 DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss:")

Tibero에 대해 간단히 설명하자면 오라클과 매우 비슷한 국산 DB인데 TmaxSoft에서 개발했습니다.

 

버전은 티베로6버전으로 진행했고 구글에 검색해도 자료가 많이 없어서 불편했습니다.

 

그래서 저처럼 시간낭비 하지마시라구 자세하게 내용정리합니다.

 

LOCAL DB FULL INSTALL이 아닌 다른 서버에 접속할수 있도록

 

Tibero6 드라이버 설치와 OLEDB 연동을 통해 DB에 접속을 해봅니다.

 

1. ODBC에 연결하기 위해서 https://technet.tmaxsoft.com 에 접속해서 다운로드 합니다.

 - 파일을 다운로드 하기위해서는 회원가입 후 로그인해야합니다.

 

드라이버 설치와 lib파일만 필요하기 때문에 하단에 256MB 파일을 다운로드합니다.

 

tbodbc_driver_installer_6_32.exe
0.12MB
tbodbc_driver_installer_6_64.exe
0.18MB

 

lib_32.zip
3.52MB
lib_64.zip
3.99MB

 

 

 

 

2. 해당 이미지와 같이 C드라이브에 폴더를 생성 후 파일을 붙여넣고 환경변수를 설정합니다.

 

 

bin 폴더안에 64bit, 32bit 해당 라이브러리 파일을 붙여넣습니다.

 

환경변수를 설정합니다.

 

 

 

 

3. 드라이버 설치를 합니다.

cmd창을 실행시킨 후 드라이버가 있는 해당 폴더로 이동한뒤 위 이미지처럼 명령어를 입력합니다.

Success to INSTALL Tibero 6 ODBC Driver 메세지가 출력되면 성공적으로 설치가 완료됐습니다.

 

 

dll을 레지스트리에 등록합니다.

마찬가지로 해당 이미지와 같이 dll도 등록해줍니다.

 

 

 

 

ODBC 관리자에 가면 정상적으로 활성화 되있는것을 확인할 수 있습니다.

 

 

 

시스템 DNS에서 추가합니다

 

 

접속하려는 서버IP와 PORT DB NAME, ID와 PWD를 입력 후 Test를 클릭해서 테스트를 해봅니다.

정상적으로 연결된 경우 Connection Success라는 메시지가 출력됩니다.

 

 

 

4. 설치가 전부 완료됐습니다. 이제 OLEDB 연동을 시작하겠습니다.

 

 

프로젝트 생성 후 해당 dll을 추가해줍니다.

 

Using System.Data.OleDb;


string sql = "Provider=tbprov.Tbprov.6; Data Source =192.168.0.1, 7000, DBTest; User ID = admin; Password=admin99;"
               + "Persist Security Info = True";              //      서버IP, PORT, DB Name;    ID;          PWD;  작성해주면 됩니다. 

            conn = new OleDbConnection(sql);
            conn.Open();

            OleDbCommand cmd = new OleDbCommand("select * from 테이블");
            cmd.Connection = conn; // Connection 초기화 하지 않으면 속성이 초기화되지 않았다는 에러메세지가 뜬다.
            OleDbDataReader read = cmd.ExecuteReader();
            while (read.Read())
            {
                string txtData = read.GetValue(1).ToString();
            }

            read.Close();
            conn.Close();

이상으로 티베로 드라이버 설치와 OLEDB 연동을 간단하게 알아보았습니다.

'Programing > Oracle' 카테고리의 다른 글

같은 테이블 다중행 삽입(MULTIPLE INSERT)  (0) 2023.01.20
상위 n개 데이터 출력  (0) 2022.02.21

이렇게 크로스 쓰레드 에러가 날 경우 해결방법

 

public void Select()
        {
            for (int i = 0; i < 2; i++)
            {
                cnt = i.ToString();
                CrossThread(tb1, cnt); 

                Thread.Sleep(3000);

            }
        }

public static void CrossThread(Control ctrl, string text)
        {
            if (ctrl.InvokeRequired)
            {
                ctrl.BeginInvoke(new MethodInvoker(delegate ()
                {
                    ctrl.Text += text;
                }));
            }
        }

이런식으로 호출할경우 해결된다.

기본 

- 10개 상위 데이터 출력

SELECT * FROM 테이블 WHERE ROWNUM <= 10

 

응용

- 정렬된 값을 10개 상위 데이터 출력

SELECT * FROM ( SELECT * FROM 테이블 ORDER BY 값 DESC ) WHERE ROWNUM <=10

'Programing > Oracle' 카테고리의 다른 글

같은 테이블 다중행 삽입(MULTIPLE INSERT)  (0) 2023.01.20
Tibero 드라이버 설치와 OleDB연동  (0) 2022.02.21

+ Recent posts