2023년 1월 25일 수요일

VC++ Unicode 와 MBSC 겸용으로 빌드시 MultiByteToWideChar/WideCharToMultiByte 함수 처리(리눅스 포함)

 VC++에서 Unicode/MBCS(Multi-Byte Character Set) 겸용으로 빌드시에 MultiByteToWideChar/WideCharToMultiByte 함수를 아래와 같이 처리하면 문제없이 빌드가 가능하다. 윈도우가 아닌 경우(리눅스 등)에도 빌드 처리가 된다.


#ifdef WIN32
#include <tchar.h>
#endif

#ifdef WIN32
#define STRNCPY _tcsncpy
#define STRLEN _tcslen
#ifdef UNICODE
#define MULTIBYTETOWIDECHAR MultiByteToWideChar
#define WIDECHARTOMULTIBYTE WideCharToMultiByte
#define SNPRINTF swprintf
#define SSCANF swscanf
#else
#define MULTIBYTETOWIDECHAR(CodePage, dwFlags, lpMultiByteStr, cbMultiByte, lpWideCharStr, cchWideChar) \
_snprintf(lpWideCharStr, cchWideChar, "%s", lpMultiByteStr)

#define WIDECHARTOMULTIBYTE(CodePage, dwFlags, lpWideCharStr, cchWideChar, lpMultiByteStr, cbMultiByte, lpDefaultChar, lpUsedDefaultChar) \
_snprintf(lpMultiByteStr, cbMultiByte, "%s", lpWideCharStr)

#define SNPRINTF _snprintf
#define SSCANF sscanf
#endif
#else
#define MULTIBYTETOWIDECHAR(CodePage, dwFlags, lpMultiByteStr, cbMultiByte, lpWideCharStr, cchWideChar) \
snprintf(lpWideCharStr, cchWideChar, "%s", lpMultiByteStr)

#define WIDECHARTOMULTIBYTE(CodePage, dwFlags, lpWideCharStr, cchWideChar, lpMultiByteStr, cbMultiByte, lpDefaultChar, lpUsedDefaultChar) \
snprintf(lpMultiByteStr, cbMultiByte, "%s", lpWideCharStr)

#define STRNCPY strncpy
#define STRLEN strlen
#define SNPRINTF snprintf
#define SSCANF sscanf

#define TCHAR char
#define TEXT(quote) quote
#define _T(quote) quote
#define __T(quote) quote
#endif

< 사용예 >
TCHAR filepathPrefix[260] = { 0 };
TCHAR fileExtension[260] = { 0 };

MULTIBYTETOWIDECHAR(CP_ACP, 0, m_szFilePathPrefix, sizeof(m_szFilePathPrefix), filepathPrefix, sizeof(filepathPrefix));

MULTIBYTETOWIDECHAR(CP_ACP, 0, m_szFileExtension, sizeof(m_szFileExtension), fileExtension, sizeof(fileExtension));

char filepathChar[256];
WIDECHARTOMULTIBYTE(CP_UTF8, 0, filepath, sizeof(filepath), filepathChar, sizeof(filepathChar), NULL, NULL);


2023년 1월 13일 금요일

vc++ 메모리 릭 감지

프로그램 시작 부분에 아래 코드 넣고 실행 후 정상종료하면 메모리릭 발생시 출력창에 메모리릭 출력 


#ifdef _DEBUG
#include <crtdbg.h>
#endif

int main()
{
#ifdef _DEBUG
_CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
#endif

간단한 strtok_s 사용법

 원본 문자열을 ',' 로 분할하고 2차원 배열에 복사하는 소스이다.


#ifdef WIN32
#define strtok_r strtok_s    // 윈도우/리눅스 빌드
#endif

char m_szRecordPath[MAX_RECORD_PATH][MAX_PATH];
int m_nRecordPathCount;

void setRecordPaths(char *filepaths)
{
memset(&m_szRecordPath, 0, sizeof(m_szRecordPath));
m_nRecordPathCount = 0;
char *ret_ptr, *next_ptr;

ret_ptr = strtok_r(filepaths, ",", &next_ptr);
while (ret_ptr) {
memcpy(&m_szRecordPath[m_nRecordPathCount], ret_ptr, strlen(ret_ptr));
m_nRecordPathCount++;
ret_ptr = strtok_r(NULL, ",", &next_ptr);
}

for (int i=0; i<m_nRecordPathCount; i++)
printf("record path[%d] : %s\n", i, m_szRecordPath[i]);
}

2022년 7월 12일 화요일

c++ 간단한 endian check 함수

int checkEndian()
{
    int i = 0x00000001;
    if( ((char *)&i)[0] ) return 0;
    else return 1;
}


리턴값이 0 이면 리틀엔디안, 1이면 빅엔디안

2022년 7월 7일 목요일

C# 유용한 ini 파일 읽기/쓰기 라이브러리 소스코드

다운로드 : IniFile.cs

c# 에서 ini 파일 읽기/쓰기를 간편하게 할 수 있는 소스코드이다.

오랫동안 유용하게 사용했는데 링크를 잊어버렸다.


< 사용법 >

using Utilities;
...
public void LoadConfig()
{
    string myExeDir = (new System.IO.FileInfo(System.Reflection.Assembly.GetEntryAssembly().Location)).Directory.ToString();
    IniFile ini = new IniFile(Path.Combine(myExeDir, "Config.ini"));
    int value1 = ini.GetInt32("SectionName", "Value1", 0);
    string value2 = ini.GetString("SectionName", "Value2", "default");
}
public void SaveConfig(int value1, string value2)
{
    string myExeDir = (new System.IO.FileInfo(System.Reflection.Assembly.GetEntryAssembly().Location)).Directory.ToString();
    IniFile ini = new IniFile(Path.Combine(myExeDir, "Config.ini"));
    ini.WriteValue("SectionName", "Value1", value1);
    ini.WriteValue("SectionName", "Value2", value2);
}

2022년 3월 21일 월요일

Qt QQueue 로 만든 간단한 template 기반 thread safe Queue 클래스

 #ifndef MYBUFFERQUEUE_H

#define MYBUFFERQUEUE_H

#include <QQueue>
#include <QMutexLocker>

template<typename T>
class MyBufferQueue
{
public:
    MyBufferQueue(int maxCount);
    virtual ~MyBufferQueue();

    int push(T *buffer);
    T* pop();

    void clear();
    int count();

private:
    QQueue<T*>      m_queue;
    QMutex          m_mutex;
    int             m_nMaxCount;
};

template <typename T>
MyBufferQueue<T>::MyBufferQueue(int maxCount)
{
    m_nMaxCount = maxCount;
}

template <typename T>
MyBufferQueue<T>::~MyBufferQueue()
{
    clear();
}

template <typename T>
int MyBufferQueue<T>::push(T *buffer)
{
    QMutexLocker locker(&m_mutex);

    if (m_nMaxCount > 0) {
        if (m_queue.count() >= m_nMaxCount)
            return -1;
    }

    m_queue.enqueue(buffer);

    return m_queue.count();
}

template <typename T>
T* MyBufferQueue<T>::pop()
{
    QMutexLocker locker(&m_mutex);

    T *image = NULL;
    if (!m_queue.isEmpty()) image = m_queue.dequeue();

    return image;
}

template <typename T>
void MyBufferQueue<T>::clear()
{
    QMutexLocker locker(&m_mutex);
    qDeleteAll(m_queue);
    m_queue.clear();
}

template <typename T>
int MyBufferQueue<T>::count()
{
    QMutexLocker locker(&m_mutex);
    return m_queue.count();
}

class AudioBuffer {
public:
    AudioBuffer() {
        data = NULL;
        size = 0;
    }

    AudioBuffer(char *_data, int _size) {
        data = new char[_size];
        memcpy(data, _data, _size);
        size = _size;
    }

    virtual ~AudioBuffer() {
        if (size > 0) delete[] data;
    }

public:
    char*   data;
    int     size;
};

#endif // MyBufferQueue_H




< 사용법 >

MyBufferQueue<AudioBuffer>*   m_pSendQue = new MyBufferQueue<AudioBuffer>(100);
...
AudioBuffer *pSendBuffer = new AudioBuffer(data, size);
m_pSendQue->push(pSendBuffer);
...
...
AudioBuffer* pBuffer = m_SendQue->pop();
...
delete pBuffer;

2021년 7월 20일 화요일

WPF WindowChrome Window Maximized 했을때 화면 잘림 현상 해결

 Window 에 아래 코드 입력


     
     private void Window_Loaded(object sender, RoutedEventArgs e)
     {
       IntPtr handle = (new WindowInteropHelper(this)).Handle;
       HwndSource.FromHwnd(handle).AddHook(new HwndSourceHook(WindowProc));
     }

     private static IntPtr WindowProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)  
     {  
       switch (msg)  
       {  
         case 0x10:  
           //Console.WriteLine("Close reason: Clicking X");  
           break;  
         case 0x11:  
         case 0x16:  
           //Console.WriteLine("Close reason: WindowsShutDown");  
           break;  
         case 0x0024:  
           WmGetMinMaxInfo(hwnd, lParam);  
           handled = true;  
           break;  
         case 0x0046:  
           NativeMethods.WINDOWPOS pos = (NativeMethods.WINDOWPOS)Marshal.PtrToStructure(lParam, typeof(NativeMethods.WINDOWPOS));  
           if ((pos.flags & (int)(NativeMethods.SWP.NOMOVE)) != 0)  
           {  
             return IntPtr.Zero;  
           }  
   
           Window wnd = (Window)HwndSource.FromHwnd(hwnd).RootVisual;  
           if (wnd == null)  
           {  
             return IntPtr.Zero;  
           }  
   
           bool changedPos = false;  
           if (pos.cx < wnd.MinWidth) { pos.cx = (int)wnd.MinWidth; changedPos = true; }  
           if (pos.cy < wnd.MinHeight) { pos.cy = (int)wnd.MinHeight; changedPos = true; }  
           if (!changedPos)  
           {  
             return IntPtr.Zero;  
           }  
   
           Marshal.StructureToPtr(pos, lParam, true);  
           handled = true;  
           break;  
         case 0x112:  
           if (((ushort)wParam & 0xfff0) == 0xf060)  
           {  
             // close (alt + F4)  
             handled = true;  
           }  
           break;  
         default:  
           break;  
       }  
       return IntPtr.Zero;  
     }  
   
     private static void WmGetMinMaxInfo(System.IntPtr hwnd, System.IntPtr lParam)  
     {  
       NativeMethods.MINMAXINFO mmi = (NativeMethods.MINMAXINFO)Marshal.PtrToStructure(lParam, typeof(NativeMethods.MINMAXINFO));  
   
       // Adjust the maximized size and position to fit the work area of the correct monitor  
       int MONITOR_DEFAULTTONEAREST = 0x00000002;  
       IntPtr monitor = NativeMethods.MonitorFromWindow(hwnd, MONITOR_DEFAULTTONEAREST);  
   
       if (monitor != System.IntPtr.Zero)  
       {  
         NativeMethods.MONITORINFO monitorInfo = new NativeMethods.MONITORINFO();  
         NativeMethods.GetMonitorInfo(monitor, monitorInfo);  
         NativeMethods.RECT rcWorkArea = monitorInfo.rcWork;  
         NativeMethods.RECT rcMonitorArea = monitorInfo.rcMonitor;  
         mmi.ptMaxPosition.x = Math.Abs(rcWorkArea.left - rcMonitorArea.left);  
         mmi.ptMaxPosition.y = Math.Abs(rcWorkArea.top - rcMonitorArea.top);  
         mmi.ptMaxSize.x = Math.Abs(rcWorkArea.right - rcWorkArea.left);  
         mmi.ptMaxSize.y = Math.Abs(rcWorkArea.bottom - rcWorkArea.top);  
       }  
       Marshal.StructureToPtr(mmi, lParam, true);  
     }  

 public class NativeMethods  
   {  
     [DllImport("user32.dll", CharSet = CharSet.Auto)]  
     internal static extern IntPtr SendMessage(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam);  
   
     // Define the Win32 API methods we are going to use  
     [DllImport("user32.dll")]  
     internal static extern IntPtr GetSystemMenu(IntPtr hWnd, bool bRevert);  
   
     [DllImport("user32.dll", CharSet = CharSet.Unicode)]  
     internal static extern bool InsertMenu(IntPtr hMenu, uint wPosition, uint wFlags, UIntPtr wIDNewItem, string lpNewItem);  
   
     [DllImport("user32.dll", CharSet = CharSet.Unicode)]  
     internal static extern int ModifyMenu(IntPtr hMenu, uint uPosition, uint wFlags, UIntPtr wIDNewItem, string text);  
   
     [DllImport("user32.dll")]  
     internal static extern bool DeleteMenu(IntPtr hMenu, uint uPosition, uint uFlags);  
   
     [DllImport("user32")]  
     public static extern bool GetMonitorInfo(IntPtr hMonitor, MONITORINFO lpmi);  
   
     [DllImport("User32")]  
     public static extern IntPtr MonitorFromWindow(IntPtr handle, int flags);  
   
     #region Win32 Imports  
     internal const UInt32 MF_BYCOMMAND = 0x00000000;  
   
     internal const UInt32 SC_SIZE = 0xF000;  
     internal const UInt32 SC_MOVE = 0xF010;  
     internal const UInt32 SC_MINIMIZE = 0xF020;  
     internal const UInt32 SC_MAXIMIZE = 0xF030;  
     internal const UInt32 SC_NEXTWINDOW = 0xF040;  
     internal const UInt32 SC_PREVWINDOW = 0xF050;  
     internal const UInt32 SC_CLOSE = 0xF060;  
     internal const UInt32 SC_VSCROLL = 0xF070;  
     internal const UInt32 SC_HSCROLL = 0xF080;  
     internal const UInt32 SC_MOUSEMENU = 0xF090;  
     internal const UInt32 SC_KEYMENU = 0xF100;  
     internal const UInt32 SC_ARRANGE = 0xF110;  
     internal const UInt32 SC_RESTORE = 0xF120;  
     internal const UInt32 SC_TASKLIST = 0xF130;  
     internal const UInt32 SC_SCREENSAVE = 0xF140;  
     internal const UInt32 SC_HOTKEY = 0xF150;  
     internal const UInt32 SC_DEFAULT = 0xF160;  
     internal const UInt32 SC_MONITORPOWER = 0xF170;  
     internal const UInt32 SC_CONTEXTHELP = 0xF180;  
     internal const UInt32 SC_SEPARATOR = 0xF00F;  
   
     /// Define our Constants we will use  
     public const Int32 WM_SYSCOMMAND = 0x112;  
     public const Int32 MF_SEPARATOR = 0x800;  
     public const Int32 MF_BYPOSITION = 0x400;  
     public const Int32 MF_STRING = 0x0;  
   
     public enum SWP : uint  
     {  
       NOSIZE = 0x0001,  
       NOMOVE = 0x0002,  
       NOZORDER = 0x0004,  
       NOREDRAW = 0x0008,  
       NOACTIVATE = 0x0010,  
       FRAMECHANGED = 0x0020,  
       SHOWWINDOW = 0x0040,  
       HIDEWINDOW = 0x0080,  
       NOCOPYBITS = 0x0100,  
       NOOWNERZORDER = 0x0200,  
       NOSENDCHANGING = 0x0400,  
     }  
   
     /// <summary>  
     /// POINT aka POINTAPI  
     /// </summary>  
     [StructLayout(LayoutKind.Sequential)]  
     public struct POINT  
     {  
       /// <summary>  
       /// x coordinate of point.  
       /// </summary>  
       public int x;  
       /// <summary>  
       /// y coordinate of point.  
       /// </summary>  
       public int y;  
   
       /// <summary>  
       /// Construct a point of coordinates (x,y).  
       /// </summary>  
       public POINT(int x, int y)  
       {  
         this.x = x;  
         this.y = y;  
       }  
     }  
   
     [StructLayout(LayoutKind.Sequential)]  
     public struct MINMAXINFO  
     {  
       public POINT ptReserved;  
       public POINT ptMaxSize;  
       public POINT ptMaxPosition;  
       public POINT ptMinTrackSize;  
       public POINT ptMaxTrackSize;  
     };  
   
     /// <summary>  
     /// </summary>  
     [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]  
     public class MONITORINFO  
     {  
       /// <summary>  
       /// </summary>        
       public int cbSize = Marshal.SizeOf(typeof(MONITORINFO));  
   
       /// <summary>  
       /// </summary>        
       public RECT rcMonitor = new RECT();  
   
       /// <summary>  
       /// </summary>        
       public RECT rcWork = new RECT();  
   
       /// <summary>  
       /// </summary>        
       public int dwFlags = 0;  
     }  
   
     [StructLayout(LayoutKind.Sequential)]  
     public struct WINDOWPOS  
     {  
       public IntPtr hwnd;  
       public IntPtr hwndInsertAfter;  
       public int x;  
       public int y;  
       public int cx;  
       public int cy;  
       public int flags;  
     }  
   
     /// <summary> Win32 </summary>  
     [StructLayout(LayoutKind.Sequential, Pack = 0)]  
     public struct RECT  
     {  
       /// <summary> Win32 </summary>  
       public int left;  
       /// <summary> Win32 </summary>  
       public int top;  
       /// <summary> Win32 </summary>  
       public int right;  
       /// <summary> Win32 </summary>  
       public int bottom;  
   
       /// <summary> Win32 </summary>  
       public static readonly RECT Empty = new RECT();  
   
       /// <summary> Win32 </summary>  
       public int Width  
       {  
         get { return Math.Abs(right - left); } // Abs needed for BIDI OS  
       }  
       /// <summary> Win32 </summary>  
       public int Height  
       {  
         get { return bottom - top; }  
       }  
   
       /// <summary> Win32 </summary>  
       public RECT(int left, int top, int right, int bottom)  
       {  
         this.left = left;  
         this.top = top;  
         this.right = right;  
         this.bottom = bottom;  
       }  
   
   
       /// <summary> Win32 </summary>  
       public RECT(RECT rcSrc)  
       {  
         this.left = rcSrc.left;  
         this.top = rcSrc.top;  
         this.right = rcSrc.right;  
         this.bottom = rcSrc.bottom;  
       }  
   
       /// <summary> Win32 </summary>  
       public bool IsEmpty  
       {  
         get  
         {  
           // BUGBUG : On Bidi OS (hebrew arabic) left > right  
           return left >= right || top >= bottom;  
         }  
       }  
       /// <summary> Return a user friendly representation of this struct </summary>  
       public override string ToString()  
       {  
         if (this == RECT.Empty) { return "RECT {Empty}"; }  
         return "RECT { left : " + left + " / top : " + top + " / right : " + right + " / bottom : " + bottom + " }";  
       }  
   
       /// <summary> Determine if 2 RECT are equal (deep compare) </summary>  
       public override bool Equals(object obj)  
       {  
         if (!(obj is Rect)) { return false; }  
         return (this == (RECT)obj);  
       }  
   
       /// <summary>Return the HashCode for this struct (not garanteed to be unique)</summary>  
       public override int GetHashCode()  
       {  
         return left.GetHashCode() + top.GetHashCode() + right.GetHashCode() + bottom.GetHashCode();  
       }  
   
   
       /// <summary> Determine if 2 RECT are equal (deep compare)</summary>  
       public static bool operator ==(RECT rect1, RECT rect2)  
       {  
         return (rect1.left == rect2.left && rect1.top == rect2.top && rect1.right == rect2.right && rect1.bottom == rect2.bottom);  
       }  
   
       /// <summary> Determine if 2 RECT are different(deep compare)</summary>  
       public static bool operator !=(RECT rect1, RECT rect2)  
       {  
         return !(rect1 == rect2);  
       }  
     }  
     #endregion  
   }