반응형

윈도우 디스플레이 배율을 확인 해 보자.

 

#include <windows.h>
#include <iostream>

void getDisplayScaleDpi(HWND hwnd) {
	/*if (hwnd == NULL)
		hwnd = GetDesktopWindow();

	UINT dpi = GetDpiForWindow(hwnd);*/

	// Get the DPI for the system.    
	UINT dpi = GetDpiForSystem();

	// Calculate scale factor: 96 DPI = 100% scale
	double scaleFactor = (double)dpi / 96.0;
	double scalePercent = scaleFactor * 100.0;

	std::cout << "DPI: " << dpi << std::endl;
	std::cout << "Scale Factor: " << scaleFactor << std::endl;
	std::cout << "Scale Percent: " << scalePercent << "%" << std::endl;
}

int main() {
	// Ensure the application is DPI aware.    
	SetProcessDpiAwarenessContext(DPI_AWARENESS_CONTEXT_SYSTEM_AWARE);
	//SetProcessDPIAware(); // same as above

	getDisplayScaleDpi(NULL);

	return 0;
}

 

 

모니터(디스플레이)의 크기를 여러가지 방법으로 확인해 보자.

#include <iostream>
#include <Windows.h>

int main() {
	HWND hWnd = GetDesktopWindow();
	if (hWnd == NULL)
		return -1;

	RECT rc;
	GetWindowRect(hWnd, &rc);
	//GetClientRect(hWnd, &rc);
	//GetWindowRect()와 같은 결과.(실제 해상도(150%): 3840 X 2160)

	std::cout << "Desktop Window Rect" << std::endl;
	std::cout << "(" << rc.left << ", " << rc.top << ")" << ", ";
	std::cout << "(" << rc.right << ", " << rc.bottom << ")" << std::endl;

	POINT pt;
	GetCursorPos(&pt);
	std::cout << "Cursor Position: " << "(" << pt.x << ", " << pt.y << ")" << std::endl;

	//HMONITOR hmon = MonitorFromWindow(hWnd, MONITOR_DEFAULTTONULL);
	HMONITOR hmon = MonitorFromPoint(pt, MONITOR_DEFAULTTONULL);
	// 마우스 포인터가 위치한 모니터를 반환한다.
	MONITORINFO mi{ .cbSize = sizeof(mi) };
	GetMonitorInfo(hmon, &mi);

	std::cout << "Monitor Rect" << std::endl;
	std::cout << "(" << mi.rcMonitor.left << ", " << mi.rcMonitor.top << ")" << ", ";
	std::cout << "(" << mi.rcMonitor.right << ", " << mi.rcMonitor.bottom << ")" << std::endl;

	return 0;
}

 

 

기본 모니터의 실제 해상도는 150% 확대되어 (3840 X 2160)이지만 (2560 X 1440)으로 표시된다.

프로그램 실행 시 마우스 커서를 보조 모니터에 두고 실행했기 때문에 두 번째 해상도는 (1920 X 1080)으로 표시된다.

(5760 - 3840 = 1920)

 

※ 참고

Confine the mouse cursor to one monitor

 

반응형
Posted by J-sean
:

Windows Mutex for Python

Python 2025. 2. 26. 11:28 |
반응형

파이썬에서 윈도우 뮤텍스를 사용해 보자.

 

아래 링크에서 namedmutex.py를 다운받고 파이썬 프로젝트에 포함시킨다.

namedmutex

namedmutex.py
0.00MB

 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
import namedmutex
#from time import sleep
 
# with namedmutex.NamedMutex('MyMutex'):
#     while True:
#         sleep(1)
#         print("Running")
 
mutex = namedmutex.NamedMutex('MyMutex')
if not mutex:
    print("Mutex not created.")
    exit(-1)
 
if not mutex.acquire(2):
    print("Mutex not acquired.")
    mutex.close()
    exit(-1)
 
input("Waiting...")
 
mutex.release()
mutex.close()
 

 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
using System;
using System.Threading;
 
public class Program
{
    public static void Main()
    {
        Mutex mutex = new Mutex(false"MyMutex");
        if (!mutex.WaitOne(2000))
        {
            Console.WriteLine("Signal not received.");
            mutex.Close();
            return;
        }
 
        Console.WriteLine("Waiting...");
        Console.ReadLine();
 
        mutex.ReleaseMutex();
        mutex.Close();
    }
}
 

 

위 파이썬 프로그램, C# 프로그램 중 중복을 포함하여 아무거나 두 개(두 번) 실행시켜 보면 MyMutex의 상황에 따라 실행 가능 여부를 확인 할 수 있다.

 

이번엔 뮤텍스를 사용해 프로그램의 중복 실행을 방지하는 코드를 살펴보자.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import namedmutex
 
mutex = namedmutex.NamedMutex('MyMutex')
if not mutex:
    print("Mutex not created.")
    exit(-1)
 
if not mutex.acquire(0):
    print("Program is running already.")
    mutex.close()
    exit(-1)
 
input("Waiting...")
 
mutex.release()
mutex.close()
 

 

위 프로그램을 실행한 상태에서 또  실행하면 두 번째 실행한 프로그램은 메세지가 출력되고 종료된다.

 

반응형
Posted by J-sean
:
반응형

아래 링크를 참조해 WinDbg를 설치한다.

Windows 디버거 설치

 

WinDbg를 실행하고 Settings를 클릭한다.

 

Debugging settings - Debugging paths - Default symbol path:에 위와같이 세팅한다.

심볼 파일이 디버깅 할 파일과 같은 경로에 있거나 path에 지정한 경로(I:\windbgsymbols)에 있으면 된다.

※ 기본 심볼 서버: https://msdl.microsoft.com/download/symbols

※ 기본 캐시 폴더: C:\ProgramData\dbg

 

Symbol path for Windows debuggers

 

디버깅할 파일을 로드하면 관련 심볼 파일도 로드된다.

 

심볼파일(.pdb)을 로드할 때 WinDbg는 타임 스템프 등을 고려한 버전 체크를 하는데 버전이 맞지 않으면 로드하지 않는다. 아래 명령을 사용하면 심볼파일의 버전에 관계없이 로드할 수 있다.

[한 모듈의 심볼파일만 로드]

.reload /i Module_Name

ex) .reload /i myapp.exe

[모든 모듈의 심볼파일 로드]

.reload /i

 

2023.07.02 - [Reverse Engineering] - WinDbg 버전(타임스템프) 일치하지 않는 심볼파일 로드하기

 

반응형
Posted by J-sean
:
반응형

안드로이드 앱은 구글 애드몹(AdMob)으로 광고를 넣을 수 있지만 윈도우 데스크탑 프로그램은 광고를 넣을 수 없다.

AdsJumbo를 이용해 C# 윈폼(WinForm) 프로그램에 광고를 넣어보자.

 

NuGet Package Manager에서 AdsJumbo를 설치한다.

 

폼 디자인너 툴박스에 AdsJumboWinForm이 추가된다.

Nuget Package 설치 후 바로 툴박스에 추가되지 않는다면 솔루션을 다시 열어준다.

 

BannerAds와 InterstitialAd를 하나씩 적당히 배치한다.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
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;
 
namespace AdsJumbo
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
 
            bannerAds1.ShowAd(72890"your_app_id");
            _ = AsyncAds();
            // Starting with C# 7.0, C# supports discards, which are placeholder
            // variables that are intentionally unused in application code.
            // Discards are equivalent to unassigned variables; they don't have
            // a value.
        }
 
        private async Task AsyncAds()
        {
            await Task.Delay(5000);
            interstitialAd1.ShowInterstitialAd("your_app_id");
            // The best place is to show an interstitial ad when the app is fully
            // loaded (eg. OnNavigated or your can simple timer await Task.Delay(2000) event)
        }
    }
}
 

 

소스를 입력하고 빌드한다.

 

 

프로그램을 실행하면 배너 광고가 표시된다.

 

5초후 전면 광고가 표시된다.

 

반응형
Posted by J-sean
:
반응형

C#에서 Windows Media Player를 이용해 오디오 파일을 플레이 해 보자.

 

아래 링크를 참고해 Windows Media Player COM Component를 가져오고 빌드시 메세지가 발생하지 않도록 하자.

(Windows Media Player 컴포넌트를 폼에 배치할 필요는 없다)

2021.11.21 - [C#] - C# Windows Media Player Audio/Video Play #1

 

폼과 버튼을 적당히 배치한다.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
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 WMPLib;
 
namespace WindowsFormsApp1
{
    public partial class Form1 : Form
    {
        private string time;
 
        WindowsMediaPlayer wmp;
 
        public Form1()
        {
            InitializeComponent();
            
            wmp = new WindowsMediaPlayer();
 
            Timer T = new Timer();
            T.Interval = 1000;
            T.Tick += new EventHandler(Form1_Timer);
            T.Start();
        }
 
        private void Form1_Timer(object sender, System.EventArgs e)
        {
            if (wmp.playState == WMPPlayState.wmppsPlaying)
            {
                //time = wmp.controls.currentPositionString + " / " + wmp.controls.currentItem.durationString;
                //time = wmp.controls.currentPosition.ToString() + " / " + wmp.controls.currentItem.duration.ToString();
                time = TimeSpan.FromSeconds((int)wmp.controls.currentPosition).ToString() + " / "
                    + TimeSpan.FromSeconds((int)wmp.controls.currentItem.duration);
 
                Graphics G = CreateGraphics();
                //G.DrawString(time, Font, System.Drawing.Brushes.Black, 20, 70); // 글자가 겹친다.
                TextRenderer.DrawText(G, time, Font, new Point(2070), ForeColor, BackColor);
                G.Dispose();
            }
        }
 
        private void button1_Click(object sender, EventArgs e)
        {
            try
            {
                OpenFileDialog dlg = new OpenFileDialog();
                if (dlg.ShowDialog() == DialogResult.OK)
                {
                    wmp.URL = dlg.FileName;
                }
            }
            catch (Exception exc)
            {
                MessageBox.Show(exc.Message);
            }
        }
 
        private void button2_Click(object sender, EventArgs e)
        {
            if (wmp.playState == WMPPlayState.wmppsPlaying)
            {
                wmp.controls.stop();
            }
        }
    }
}
 

 

소스를 입력한다.

 

오디오/비디오 파일을 플레이 할 수 있다. (비디오 파일은 오디오만 출력된다)

실행 파일과 함께 Interop.WMPLib.dll 파일이 존재해야 한다.

 

Using the Windows Media Player Control in a .NET Framework Solution

 

반응형
Posted by J-sean
:
반응형

 

2021.11.21 - [C#] - C# Windows Media Player Audio/Video Play #2

 

C#에서 Windows Media Player를 이용해 오디오/비디오 파일을 플레이 해 보자.

 

Toolbox의 원하는 곳에서 우클릭 - Choose Items...

 

COM Components - Windows Media Player 선택.

 

폼, 버튼, Windows Media Player를 적당히 배치한다.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
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 WMPLib;
 
namespace WindowsFormsApp1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }
 
        private void button1_Click(object sender, EventArgs e)
        {
            try
            {
                OpenFileDialog dlg = new OpenFileDialog();
                if (dlg.ShowDialog() == DialogResult.OK)
                {
                    axWindowsMediaPlayer1.URL = dlg.FileName;
                    axWindowsMediaPlayer1.Ctlcontrols.stop();   // 자동 재생 방지.
                    // The managed-code wrapper for the Windows Media Player control exposes
                    // the Controls object as Ctlcontrols to avoid collision with the Controls
                    // property inherited from System.Windows.Forms.Control.
                }
            }
            catch (Exception exc)
            {
                MessageBox.Show(exc.Message);
            }
        }
    }
}
 

 

소스를 입력한다.

 

 

이대로 빌드해도 문제는 없지만 위와 같은 메세지가 나온다.

 

References - WMPLib - Properties - Embed Interop Types - False 선택

다시 빌드하면 아무 메세지도 나오지 않는다.

 

MP3등 오디오 파일 재생.

 

AVI, MP4등 비디오 파일 재생.

 

 

이번엔 실행하면 아무것도 보이지 않다가 오디오/비디오 파일을 선택하면 UI없이 플레이 하는 프로그램을 만들어 보자.

 

폼, 버튼, Windows Media Player를 배치한다.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
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 WMPLib;
 
namespace WindowsFormsApp1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
 
            axWindowsMediaPlayer1.Visible = false;
            axWindowsMediaPlayer1.uiMode = "none";
        }
 
        private void button1_Click(object sender, EventArgs e)
        {
            try
            {
                OpenFileDialog dlg = new OpenFileDialog();
                if (dlg.ShowDialog() == DialogResult.OK)
                {
                    axWindowsMediaPlayer1.URL = dlg.FileName;
                    axWindowsMediaPlayer1.Visible = true;
                }
            } catch (Exception exc)
            {
                MessageBox.Show(exc.Message);
            }
        }
 
        private void button2_Click(object sender, EventArgs e)
        {
            if (axWindowsMediaPlayer1.playState == WMPPlayState.wmppsPlaying)
            {
                axWindowsMediaPlayer1.Ctlcontrols.stop();
                // The managed-code wrapper for the Windows Media Player control exposes
                // the Controls object as Ctlcontrols to avoid collision with the Controls
                // property inherited from System.Windows.Forms.Control.
                
                axWindowsMediaPlayer1.Visible = false;
            }            
        }
    }
}
 

 

소스를 입력하고 빌드한다.

 

WMP가 보이지 않는다. Play 버튼을 클릭하고 비디오 파일을 선택한다.

 

비디오가 UI없이 플레이된다.

 

실행 파일과 함께 Interop.WMPLib.dll 파일이 존재해야 한다.

 

Using the Windows Media Player Control in a .NET Framework Solution

 

반응형
Posted by J-sean
:

OpenCV with C#

OpenCV 2021. 11. 20. 10:22 |
반응형

C#으로 OpenCV를 사용해 보자.

 

새로운 프로젝트를 만든다.

 

C# - Windows - Desktop - Windows Forms App (.NET Framework)

 

적당한 이름과 위치를 지정한다.

 

Tools - Nuget Package Manager - Manage Nuget Packages for Solution...

 

 

Browse - OpenCV를 검색하고 OpenCvSharp4.Windows by shimat 선택, 오른쪽 창에서 현재 프로젝트(OpenCV)를 선택하고 Install을 클릭한다.

 

OK를 클릭한다.

 

설치가 완료되면 폼에 Button과 Picture Box를 하나씩 배치한다.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
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 OpenCvSharp;
 
namespace OpenCV
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }
 
        private void button1_Click(object sender, EventArgs e)
        {
            try
            {
                OpenFileDialog dlg = new OpenFileDialog();
                if (dlg.ShowDialog() == DialogResult.OK)
                {
                    Mat mat = Cv2.ImRead(dlg.FileName);
 
                    if (pictureBox1.Image != null)
                    {
                        pictureBox1.Image.Dispose();
                    }
 
                    // Mat to Bitmap 1
                    //Bitmap bitmap = new Bitmap(mat.ToMemoryStream());
                    //pictureBox1.Image = bitmap;
 
                    // Mat to Bitmap 2
                    //Bitmap bitmap = (Bitmap)Image.FromStream(mat.ToMemoryStream());
                    //pictureBox1.Image = bitmap;
 
                    // Mat to Bitmap 3
                    System.IO.MemoryStream memoryStream = new System.IO.MemoryStream(mat.ToBytes());
                    pictureBox1.Image = new Bitmap(memoryStream);
                }
            }
            catch (Exception exc)
            {
                MessageBox.Show(exc.Message);
            }
        }
    }
}
 

 

OpenCvSharp를 using 선언하고 버튼 클릭 이벤트 핸들러를 작성한다.

 

 

실행하고 버튼을 클릭해 적당한 그래픽 파일을 선택한다.

 

 

※ 참고

1. 인터넷 사용이 불가능한 컴퓨터라면 아래 링크에서 release된 dll 파일을 다운받고 직접 reference에 추가하여 사용하면 된다.

OpenCvSharp

 

2. API 레퍼런스

OpenCvSharp API Reference

 

반응형
Posted by J-sean
:
반응형

Linux가 아닌 Windows에서는 Microsoft Visual C++을 사용하는 경우가 많다. 아래 링크와 같이 Qt를 설치한다.

2021.09.25 - [C, C++] - Qt6 설치 및 간단한 사용법

 

Qt Widgets Application 프로젝트를 생성하고 프로젝트명.pro 파일을 확인한다.

 

프로젝트명.pro 파일을 위와 같이 수정한다. (opencv는 C:\opencv에 설치되어 있다)

CONFIG(debug, debug|release) {
    LIBS += -lopencv_world453d
}

CONFIG(release, debug|release) {
    LIBS += -lopencv_world453
}

opencv_world453은 C:\opencv\build\x64\vc15\bin 폴더의 opencv_worldXXX.dll, opencv_worldXXXd.dll 파일을 참고해 작성한다.

 

Projects - Build & Run - Run - Environment - Path 에 C:\opencv\build\x64\vc15\bin을 추가한다.

 

UI Design에서 Pushbutton을 하나 추가하고 우클릭 - Go to slot...을 클릭한다.

 

 

clicked()를 선택한다.

 

on_pushButton_clicked()를 위와 같이 수정한다. (상단에 opencv.hpp가 include 되어있다)

 

프로젝트를 빌드하고 XXX-Debug 폴더에 사진 파일을 복사한다.

 

실행하면 위와 같은 위도우가 나타난다. PushButton을 클릭하자.

 

 

Barbara palvin 사진이 출력된다.

 

반응형
Posted by J-sean
: