태터데스크 관리자

도움말
닫기
적용하기   첫페이지 만들기

태터데스크 메시지

저장하였습니다.

티스토리 툴바


프로그래밍2012/04/27 17:38

현재 프로젝트가 Unity3D를 이용하여 개발을 진행하다 보니 일일 자동 빌드의 필요성이 있어 해당 기능을 적용하였다.

우선 자동 빌드를 하기 위한 시스템에는 유니티 에디터가(빌더,컴파일러) 설치되어 있어야 한다.

SCM은 SVN 대신 UnityAsset Server 를 쓰고 있으며 기본 플로우는 다음과 같다.


  1. AssetServer에서 최신 리소스 및 코드 다운로드.
  2. 빌드 진행.

    (너무심플하다)


물론 SVN이나 다른 것을 사용한다면 1번과정을 대체하면 된다.

유니티에서는 명령줄 입력을 지원하므로 AssetServer에서 최신데이터 다운로드 및2번 빌드 과정은 unity.exe 를 이용한다.

 

우선 배치파일을 아래와 같은 내용으로 작성한다. 명령줄에 대한 설명은 유니티 도움말 참조!!


Unity_build.bat

@echo off

net use x: \\fileserver\Project /user:user pass

Echo [Process batchjob]===================================================== >> unitybuild.log

Echo %date% %time% [START] Update >> unitybuild.log

@"D:\Program(x86)\Unity\Editor\Unity.exe" -batchmode -projectPath D:\Work\TalesStory -assetServerUpdate 175.211.69.106 TalesStory user pass -quit -nographics >> unitybuild.log

Echo %date% %time% [BUILD] Unity batch build >> unitybuild.log

@"D:\Program(x86)\Unity\Editor\Unity.exe" -quit -batchmode -projectPath D:\Work\TalesStory -nographics -executeMethod MyEditorScript.PerformBuild >> unitybuild.log

Echo %date% %time% [END] >> unitybuild.log

 

net use 를 하는 것은 상기 배치파일을 서비스스케줄러에서 돌리게 되어 결과물이 저장될 서버에 미리 로그인해두는 것이다.

다음은 명령줄에서 실행할 스크립트 메서드(Batchbuild.cs)를 작성하여 Asset/Editor 폴더에 복사한다.

UnityEditor.MenuItem 을 이용해서 유니티 메뉴에 등록하여 빌드 테스트도 가능하다.


 

Batchbuild.cs

 

using UnityEngine;

using UnityEditor;

using System;

 

class MyEditorScript: ScriptableObject

{

    public static string version = PlayerSettings.bundleVersion;

    private static string version_template = "public class Version {    public static string version = \"$$version$$\";}";

 

    //-----------------------------------------------------------------------------------------------------------------

    [UnityEditor.MenuItem("Tools/G Studio/About G Studio")]

    static void About(){

        //요기다 디버그 찍어보자.

        Debug.Log("Application.dataPath="+Application.dataPath);

        Debug.Log("version="+version);

        Debug.Log("Version.version="+Version.version);

 

        WriteVersionFile(Application.dataPath+@"\Source\GUIScripts\Version.cs",version_template.Replace("$$version$$","adfasdfasdf"));

 

        EditorUtility.DisplayDialog("G Studio v" + version, "G Studio Test Script Version " + version + "\n\nCopyright 2012 NEOCYON G Studio\nAll rights reserved.", "OK");

    }

    //-----------------------------------------------------------------------------------------------------------------

    [UnityEditor.MenuItem("Tools/G Studio/PerformBuild")]

static void PerformBuild()

{

         string dt = String.Format(@"{0:yyyyMMdd}", DateTime.Now);

         PlayerSettings.Android.bundleVersionCode +=1;

         PlayerSettings.bundleIdentifier = "com.neocyon.talesstory";

         PlayerSettings.bundleVersion = "1.0." +PlayerSettings.Android.bundleVersionCode+"."+ dt;

        WriteVersionFile(Application.dataPath+@"\Source\GUIScripts\Version.cs",

                        version_template.Replace("$$version$$",PlayerSettings.bundleVersion));

 

        Debug.Log("PerformBuild()-Debug.Log");

//Console.WriteLine("PerformBuild()-Console");        //요건 안찍힘.

string output = "X:/40.배포/배치빌드/tailstory_" + dt + "-" + PlayerSettings.Android.bundleVersionCode+".apk";

string[] scenes = {

             Application.dataPath+"/Scenes/LoadScene.unity",

             Application.dataPath+"/Scenes/GameScene.unity"

             };

BuildPipeline.BuildPlayer(scenes, output, BuildTarget.Android ,BuildOptions.None );

}

    

    //-----------------------------------------------------------------------------------------------------------------    

    [UnityEditor.MenuItem("Tools/G Studio/Update Asset Server Data")]

static void UpdateAssetfromServer()

{

        Debug.Log("UpdateAssetfromServer()-Debug.Log");

        AssetDatabase.Refresh(ImportAssetOptions.Default);

//Console.WriteLine("PerformBuild()-Console");        //요건 안찍힘.

        //업데이트 수행하는 메서드 못찾음.

}

    //-----------------------------------------------------------------------------------------------------------------

     private static void WriteVersionFile(string filePathname, string version)

     {

        using (System.IO.FileStream fs = System.IO.File.Create(filePathname))

        {

            byte[] info = new System.Text.UTF8Encoding(true).GetBytes(version);

            fs.Write(info, 0, info.Length);

            //fs.WriteText(version);

        }        

     }

}

 

코드에 필요한 게 있다면 편집하면 된다.

프로젝트명-빌드날짜.apk로 빌드 되도록 구성하였다.

 

여기에다가 빌드시 자동으로 빌드일자를 프로그램 내에 삽입하기 위하여 Version 클래스를 작성하고 참조하고 빌드전에 version.cs를 자동 생성시켜 내부에 버전정보를 표시토록 한다.

 

이후 윈도우 작업 스케줄러 에 해당 배치파일을 등록하면 끝.


매일 새벽 5시에 빌드가 된다. 자~알 된다. 아 물론 5시에 시스템 켜있어야한다. 그리고 유니티는 실행중이면 안된다. process 검사해서 kill 해주고 빌드 돌리는거 만들려다가 구차니즘으로 걍 pass!~


저작자 표시 비영리 변경 금지
크리에이티브 커먼즈 라이선스
Creative Commons License
Posted by 벌커덕스
프로그래밍2011/06/23 10:31
UI 스레드에 갱신요청하기 위해 아래처럼 대리자, 콜러, 본체로 나눠서 코딩하다가 간단하게 할수 있는 방법을 발견 !!

public delegate void ShowButtonDelegate(bool IsShow);
public void ShowButtonCaller(bool IsShow)
{
    if (canvasButtonGroup.Dispatcher.CheckAccess())
        ShowButtonBody(IsShow);
    else
        Dispatcher.Invoke(new ShowButtonDelegate(ShowButtonBody), IsShow);
}
private void ShowButtonBody(bool IsShow)
{
    DebugWrite("ShowButtonBody =" + IsShow.ToString());
}
------------------------------------
윈폼 ----------------------------
this.Invoke(new MethodInvoker(delegate()
{
    mnuConnectServer.Enabled = true;
    mnuStartServer.Enabled = true;
}));
------------------------------------
WPF ----------------------------
MainUI.Dispatcher.BeginInvoke(System.Windows.Threading.DispatcherPriority.Normal, 
new DispatcherOperationCallback(delegate {     MainUI.ResetGame(user.m_nID);     return null
}), null);  


------------------------------------
Invoke : 동기
BeginInvoke : 비동기  

------------------------------------
 
저작자 표시 비영리 동일 조건 변경 허락
크리에이티브 커먼즈 라이선스
Creative Commons License
Posted by 벌커덕스
TAG c#,
bcdedit.exe 를 이용해서 이런저런 작업을 하다 보면 제일 자주 하는게 /? 입력해서 확인하는거다. 정리를 한번 해둘 필요는 느끼긴하지만 그것도 차일피일 미루다가..

우선 웹검색을 해보니 커맨드 관련해서 마이크로소프트에서 나온 문서가 있다.
docx 파일이라 간단하게 보긴 어렵고 해서 붙여놓는다.
따로 정리하지 않고 docx문서 통채 붙여놓는거라 찾기로 찾아봐야한다.
필요시 열어서 보도록 하자..
원본링크는 http://msdn.microsoft.com/en-us/windows/hardware/gg463064.aspx

그래도 /? 는 앞으로 죽을때까지 애용될거 같은 느낌이...

더보기

 
아 그러고보니 bcdedit 관련해서는 여러 툴들이 존재하는데 그중 visualbcd 라는 놈이 제일이란다.
다른툴은 bcdedit.exe 에서 제공하는 모든 기능을 다 쓸수없고 자주 쓰는 기능만 사용한다는데 visualbcd 는 개발자가 마이크로 소프트에서 제공하는 bcd 관련 WMI Provider를 이용하여 개발한듯하다. 닷넷프레임웍 4 이상이 필요하다고 하니 배보다 배꼽이 더 클수도 있겠다.
 
저작자 표시 비영리 동일 조건 변경 허락
크리에이티브 커먼즈 라이선스
Creative Commons License

'프로그래밍 > 표준문서' 카테고리의 다른 글

bcdedit.exe Document  (0) 2011/06/06
GRUB 명령어 정의 문서  (0) 2009/03/24
Posted by 벌커덕스
프로그래밍2011/05/09 16:29
Visual Studio 는 도구로 명령프롬프트를 별도의 배치파일로 제공을 한다.

Visual Studio 2010을 사용하면서 간단한 코드들은 Notepad++을 이용하여 소스코드 컴파일 및 테스트를 해보는데
Notepad++ 에서 컴파일 환경을 세팅하기위해서는 명령프롬프트에서 제공하는 것처럼 시스템 환경변수가 필요하다.

이는 모든 텍스트 편집기에서 컴파일하기위한 환경이라고 보면 될듯..

환경변수는 아래와 같은 것들이 추가가 되는데 시스템에 맞는 경로로 추가해주거나 편집해주면 됨.


 
DevEnvDir=C:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\IDE\

Framework35Version=v3.5
FrameworkDir=C:\Windows\Microsoft.NET\Framework\
FrameworkDIR32=C:\Windows\Microsoft.NET\Framework\
FrameworkVersion=v4.0.30319
FrameworkVersion32=v4.0.30319

INCLUDE=C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\INCLUDE;
   C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\ATLMFC\INCLUDE;
C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\include;

LIB=C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\LIB;
C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\ATLMFC\LIB;
C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\lib;
LIBPATH=C:\Windows\Microsoft.NET\Framework\v4.0.30319;
C:\Windows\Microsoft.NET\Framework\v3.5;
C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\LIB;
C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\ATLMFC\LIB;

Path=C:\Program Files (x86)\Microsoft Visual Studio 10.0\VSTSDB\Deploy;
C:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\IDE\;
C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\BIN;
C:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\Tools;
C:\Windows\Microsoft.NET\Framework\v4.0.30319;
C:\Windows\Microsoft.NET\Framework\v3.5;
C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\VCPackages;
C:\Program Files (x86)\HTML Help Workshop;
C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Performance Tools;
C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\bin\NETFX 4.0 Tools;
C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\bin;

VCINSTALLDIR=C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\
VS100COMNTOOLS=C:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\Tools\
VSINSTALLDIR=C:\Program Files (x86)\Microsoft Visual Studio 10.0\

WindowsSdkDir=C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\



 
 
저작자 표시 비영리 동일 조건 변경 허락
크리에이티브 커먼즈 라이선스
Creative Commons License
Posted by 벌커덕스
프로그래밍2009/12/17 21:49
MSDN 에서 발췌..
원본 주소는
http://msdn.microsoft.com/ko-kr/library/d9x1s805(en-us,VS.80).aspx



Each implementation of C and C++ supports some features unique to its host machine or operating system. Some programs, for instance, need to exercise precise control over the memory areas where data is placed or to control the way certain functions receive parameters. The #pragma directives offer a way for each compiler to offer machine- and operating system-specific features while retaining overall compatibility with the C and C++ languages. Pragmas are machine- or operating system-specific by definition, and are usually different for every compiler.

Pragmas can be used in conditional statements, to provide new preprocessor functionality, or to provide implementation-defined information to the compiler. The Microsoft C and C++ compilers recognize the following pragmas:

1. Supported only by the C++ compiler.

The token-string is a series of characters that gives a specific compiler instruction and arguments, if any. The number sign (#) must be the first non-white-space character on the line containing the pragma; white-space characters can separate the number sign and the word pragma. Following #pragma, write any text that the translator can parse as preprocessing tokens. The argument to #pragma is subject to macro expansion.

If the compiler finds a pragma it does not recognize, it issues a warning, but compilation continues.

Some pragmas provide the same functionality as compiler options. When a pragma is encountered in source code, it overrides the behavior specified by the compiler option. For example, if you specified /Zp8, you can override this compiler setting for specific portions of the code with pack:

저작자 표시 비영리 동일 조건 변경 허락
크리에이티브 커먼즈 라이선스
Creative Commons License
Posted by 벌커덕스
TAG c++, 지시어
프로그래밍2009/07/14 16:19
VS 2003 의 경우 레지스트리를 직접 백업 받아서 사용해야 했으나 2005부터는 export 해서 따로 저장이 가능하다.
도구 - 설정 내보내기 및 가져오기 메뉴를 통해 필요한 부분을 백업받거나 가져올수 있다.

원래부터 검정배경을 좋아하기 때문에 검정으로 수정해서 사용하고 있고 
어시스트를 사용한다면 같이 세팅해주어야 효과가 좋다. 
여러 버전의 비주얼 스튜디오가 설치된 경우에도 어시스트는 하나의 파일로 익스포트가 된다.


비주얼 스튜디오 2005의 색상 설정파일 :

어시스트 설정파일 :


이전 참고글
2009/05/30 - [프로그래밍] - VS 2003 컬러 스키마


저작자 표시 비영리 동일 조건 변경 허락
크리에이티브 커먼즈 라이선스
Creative Commons License
Posted by 벌커덕스
TAG vs
프로그래밍2009/07/14 01:33
게임데이터를 엑셀을 이용해서 작성하고 엑셀의 VBA 를 이용해 DB로 다이렉트로 전송하곤 하는데 
휠이 안돈다.
MS에서는 다음링크에서 그 방법을 제시하고 있다.
위의 예에서 보면 코드편집기의 ide의 추가기능을 이용하여 휠을 적용하게끔 하고 있다.
관련파일은 
에서 다운로드 받을수 있고
위의 파일안에 있는 코드는 다음과 같고 왜 휠이 적용되는지 궁금하면 소스를 분석해보면 될듯하다.

추가적으로 휠을 적용할수 있는 다른 방법은 
1. mouse driver 를 로지텍 드라이버나 MS 인텔리 포인트를 사용하는 방법과
2. Autohotkey 와 같은 스크립트를 이용해서 스크립트를 짜서 붙이는 방법 도 있다.


---------------------------------------------------------------------------------------------
Attribute VB_Name = "Main"
Option Explicit

Declare Function EnumChildWindows Lib "user32" (ByVal hWndParent _
   As Long, ByVal lpEnumFunc As Long, ByVal lParam As Long) As Long

Declare Function EnumThreadWindows Lib "user32" (ByVal dwThreadId _
   As Long, ByVal lpfn As Long, ByVal lParam As Long) As Long

Declare Function GetClassName Lib "user32" Alias "GetClassNameA" _
   (ByVal hWnd As Long, ByVal lpClassName As String, _
   ByVal nMaxCount As Long) As Long

Declare Function GetWindowText Lib "user32" Alias "GetWindowTextA" _
   (ByVal hWnd As Long, ByVal lpString As String, _
   ByVal cch As Long) As Long

Public Declare Function GetCurrentThreadId Lib "kernel32" () As Long

Public Declare Function CallWindowProc Lib "user32" Alias _
"CallWindowProcA" _
    (ByVal lpPrevWndFunc As Long, ByVal hWnd As Long, ByVal msg As Long, _
    ByVal wParam As Long, ByVal lParam As Long) As Long

Public Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" _
    (ByVal hWnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) _
    As Long
    
Public Declare Function SendMessage Lib "user32" Alias "SendMessageA" _
    (ByVal hWnd As Long, ByVal wMsg As Long, ByVal wParam As _
    Long, ByVal lParam As Long) As Long

Public Declare Function WindowFromPointXY Lib "user32" _
               Alias "WindowFromPoint" (ByVal xPoint As Long, _
               ByVal yPoint As Long) As Long
               
Private Declare Function SystemParametersInfo Lib "user32" _
        Alias "SystemParametersInfoA" _
        (ByVal uAction As Long, _
        ByVal uParam As Long, _
        lpvParam As Any, _
        ByVal fuWinIni As Long) As Long

Public Declare Function PostMessage Lib "user32" Alias "PostMessageA" (ByVal hWnd As Long, ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
Public Declare Function WindowFromPoint Lib "user32" (pt As POINTAPI) As Long
Public Declare Function GetWindowInfo Lib "user32" (ByVal hWnd As Long, ByRef pwi As WINDOWINFO) As Boolean

Public Declare Function LoadLibrary Lib "kernel32" Alias "LoadLibraryA" (ByVal lpLibFileName As String) As Long
Public Declare Function FreeLibrary Lib "kernel32" Alias "FreeLibraryA" (ByVal hLibrary As Long) As Boolean


Private Type RECT
   Left As Long
   Top As Long
   Right As Long
   Bottom As Long
End Type

Private Type WINDOWINFO
    cbSize As Long
    rcWindow As RECT
    rcClient As RECT
    dwStyle As Long
    dwExStyle As Long
    cxWindowBorders As Long
    cyWindowBorders As Long
    atomWindowtype As Long
    wCreatorVersion As Long
End Type

Private Type POINTAPI
  x As Long
  y As Long
End Type

Private Type MOUSEHOOKSTRUCT
  pt As POINTAPI
  hWnd As Long
  wHitTestCode As Long
  dwExtraInfo As Long
End Type

Private Type MSLLHOOKSTRUCT
    pt As POINTAPI
    mouseData As Long
    flags As Long
    time As Long
    dwExtraInfo As Long
End Type

Private Const WM_MOUSEWHEEL = &H20A
Private Const WM_MBUTTONUP = &H208
Private Const WM_MBUTTONDOWN = &H207
Private Const WM_MBUTTONDBLCLK = &H209
Private Const WM_LBUTTONDOWN = &H201
Private Const WM_LBUTTONUP = &H202
Private Const WM_RBUTTONUP = &H205

Private Const MK_LBUTTON = &H1
Private Const MK_MBUTTON = &H10
Private Const MK_RBUTTON = &H2

Public Const WH_MOUSE = 7
Private Const WHEEL_DELTA = 120

Private Const WM_VSCROLL = &H115
Private Const WM_USER As Long = &H400
Private Const WM_SOMETHING = WM_USER + 3139

Public Const GWL_WNDPROC = -4
Public Const WH_MOUSE_LL = 14

Public Const SB_LINEUP = 0
Public Const SB_LINELEFT = 0
Public Const SB_LINEDOWN = 1
Public Const SB_LINERIGHT = 1
Public Const SB_ENDSCROLL = 8
Public Const WS_VISIBLE = &H10000000
Public Const SBS_VERT = 1
Public Const SBS_HORZ = 0
Public Const WM_HSCROLL = &H114
Public Const SPI_GETWHEELSCROLLLINES = 104

Public Enum mButtons
  LBUTTON = &H1
  MBUTTON = &H10
  RBUTTON = &H2
End Enum

   Public Const REG_SZ As Long = 1
   Public Const REG_DWORD As Long = 4

   Public Const HKEY_CLASSES_ROOT = &H80000000
   Public Const HKEY_CURRENT_USER = &H80000001
   Public Const HKEY_LOCAL_MACHINE = &H80000002
   Public Const HKEY_USERS = &H80000003

   Public Const ERROR_NONE = 0
   Public Const ERROR_BADDB = 1
   Public Const ERROR_BADKEY = 2
   Public Const ERROR_CANTOPEN = 3
   Public Const ERROR_CANTREAD = 4
   Public Const ERROR_CANTWRITE = 5
   Public Const ERROR_OUTOFMEMORY = 6
   Public Const ERROR_ARENA_TRASHED = 7
   Public Const ERROR_ACCESS_DENIED = 8
   Public Const ERROR_INVALID_PARAMETERS = 87
   Public Const ERROR_NO_MORE_ITEMS = 259

   Public Const KEY_QUERY_VALUE = &H1
   Public Const KEY_SET_VALUE = &H2
   Public Const KEY_ALL_ACCESS = &H3F

   Public Const REG_OPTION_NON_VOLATILE = 0

   Declare Function RegCloseKey Lib "advapi32.dll" _
        (ByVal hKey As Long) As Long
   
   Declare Function RegCreateKeyEx Lib "advapi32.dll" Alias _
        "RegCreateKeyExA" (ByVal hKey As Long, ByVal lpSubKey As String, _
        ByVal Reserved As Long, ByVal lpClass As String, ByVal dwOptions _
        As Long, ByVal samDesired As Long, ByVal lpSecurityAttributes _
        As Long, phkResult As Long, lpdwDisposition As Long) As Long
   
   Declare Function RegOpenKeyEx Lib "advapi32.dll" Alias _
        "RegOpenKeyExA" (ByVal hKey As Long, ByVal lpSubKey As String, _
        ByVal ulOptions As Long, ByVal samDesired As Long, phkResult As _
        Long) As Long
   
   Declare Function RegQueryValueExString Lib "advapi32.dll" Alias _
        "RegQueryValueExA" (ByVal hKey As Long, ByVal lpValueName As _
        String, ByVal lpReserved As Long, lpType As Long, ByVal lpData _
        As String, lpcbData As Long) As Long
            
   Declare Function RegQueryValueExLong Lib "advapi32.dll" Alias _
        "RegQueryValueExA" (ByVal hKey As Long, ByVal lpValueName As _
        String, ByVal lpReserved As Long, lpType As Long, lpData As _
        Long, lpcbData As Long) As Long
   
   Declare Function RegQueryValueExNULL Lib "advapi32.dll" Alias _
        "RegQueryValueExA" (ByVal hKey As Long, ByVal lpValueName As _
        String, ByVal lpReserved As Long, lpType As Long, ByVal lpData _
        As Long, lpcbData As Long) As Long
   
   Declare Function RegSetValueExString Lib "advapi32.dll" Alias _
        "RegSetValueExA" (ByVal hKey As Long, ByVal lpValueName As String, _
        ByVal Reserved As Long, ByVal dwType As Long, ByVal lpValue As _
        String, ByVal cbData As Long) As Long
    
   Declare Function RegSetValueExLong Lib "advapi32.dll" Alias _
       "RegSetValueExA" (ByVal hKey As Long, ByVal lpValueName As String, _
        ByVal Reserved As Long, ByVal dwType As Long, lpValue As Long, _
       ByVal cbData As Long) As Long

Dim nKeys As Long, Delta As Long, XPos As Long, YPos As Long
Dim OriginalWindowProc As Long
Dim pthWnd As Long
Dim lLineNumbers As Long
Dim MainWindowHwnd As Long  ' Main IDE window handle
Dim bHook As Boolean
Dim sLib As String
Dim hLib As Long

Public Function WindowProc(ByVal hWnd As Long, ByVal uMsg As Long, _
                           ByVal wParam As Long, ByVal lParam As Long) _
                           As Long
    Select Case uMsg
      Case WM_MOUSEWHEEL
        nKeys = wParam And 65535
        Delta = wParam / 65536 / WHEEL_DELTA

        XPos = LowWord(lParam)
        YPos = HighWord(lParam)
        
        pthWnd = WindowFromPointXY(XPos, YPos)
                
        ' Get the scroll bar for this window and send the vscroll to it
        Dim lret As Long
        lret = EnumChildWindows(pthWnd, AddressOf EnumChildProc, lParam)
               
    End Select

    If OriginalWindowProc <> 0 Then
        WindowProc = CallWindowProc(OriginalWindowProc, hWnd, uMsg, wParam, lParam)
    End If
End Function

Public Sub UnHook()

    'Ensures that you don't try to unsubclass the window when
    'it is not subclassed.
    If OriginalWindowProc = 0 Then Exit Sub
    

    'Reset the window's function back to the original address.
    Dim hr As Long
    hr = SetWindowLong(MainWindowHwnd, GWL_WNDPROC, OriginalWindowProc)
    If hr <> 0 Then
        OriginalWindowProc = 0
        bHook = False
    Else
        Debug.Print "Unable to unhook:  SetWindowLong returns " & vbCrLf & hr & vbCrLf & Err.LastDllError
    End If
    
End Sub

Public Sub Hook()
    On Error GoTo Error
    
    ' GetLine Numbers
    SystemParametersInfo SPI_GETWHEELSCROLLLINES, 0, lLineNumbers, 0
    
    ' Adjust just in case, otherwise we'll never get the scroll notification.
    If lLineNumbers = 0 Then
        lLineNumbers = 1
    End If
    
    OriginalWindowProc = SetWindowLong(MainWindowHwnd, GWL_WNDPROC, AddressOf WindowProc)
    
    ' Set a flag indicating that we are hooking
    bHook = True
    
    ' Find out where we live on the filesystem
    Dim lRetVal As Long
    Dim sKeyName As String
    Dim sValue As String
    sKeyName = "CLSID\{B84F8C6E-BDDE-4384-9946-82EEE7F81D48}\InprocServer32"
    sValue = QueryValue(sKeyName, "")
    
    ' If we found where we live let's increase our ref count so we can do our own cleanup later
    If Len(sValue) > 0 Then
        sLib = sValue
        hLib = LoadLibrary(sLib)
    End If
        
    Exit Sub
    
Error:
    Debug.Print "Unable to set hook:  " & vbCrLf & Err.Description & vbCrLf & Err.LastDllError
End Sub

Function EnumChildProc(ByVal lhWnd As Long, ByVal lParam As Long) _
   As Long
   Dim RetVal As Long
   Dim WinClassBuf As String * 255, WinTitleBuf As String * 255
   Dim WinClass As String, WinTitle As String
   Dim WinRect As RECT
   Dim WinWidth As Long, WinHeight As Long

   RetVal = GetClassName(pthWnd, WinClassBuf, 255)
   WinClass = StripNulls(WinClassBuf)  ' remove extra Nulls & spaces
   RetVal = GetWindowText(lhWnd, WinTitleBuf, 255)
   WinTitle = StripNulls(WinTitleBuf)
   
   ' see the Windows Class and Title for each Child Window enumerated
   'Debug.Print "   hWnd = " & Hex(lhWnd) & " Child Class = "; WinClass; ", Title = "; WinTitle
   ' You can find any type of Window by searching for its WinClass
   Dim lret As Long
   Dim i As Long
   
   ' Since we can have split windows we need to figure out which scroll bar to move.
   ' We can do this by comparing the Y position of the cursor against the vertical scrollbars
   ' that are children of the current window
   Dim wi As WINDOWINFO
   wi.cbSize = Len(wi)
   If GetWindowInfo(lhWnd, wi) And WinClass <> "MDIClient" Then
        If IsVerticalScrollBar(lhWnd) = True And wi.rcWindow.Top < YPos And wi.rcWindow.Bottom > YPos Then    ' TextBox Window
          
             If Delta > 0 Then                       ' Scroll Up
                  Do While i < Delta * lLineNumbers
                     lret = PostMessage(pthWnd, WM_VSCROLL, SB_LINEUP, lhWnd)
                     i = i + 1
                  Loop
              Else                                   ' Scroll Down
                  Do While i > Delta * lLineNumbers
                     lret = PostMessage(pthWnd, WM_VSCROLL, SB_LINEDOWN, lhWnd)
                     i = i - 1
                  Loop
              End If
        ElseIf IsHorizontalScrollBar(lhWnd) = True Then
             If Delta > 0 Then                       ' Scroll Left
                 Do While i < Delta * lLineNumbers
                     lret = PostMessage(pthWnd, WM_HSCROLL, SB_LINELEFT, lhWnd)
                     i = i + 1
                 Loop
              Else                                   ' Scroll Right
                 Do While i > Delta * lLineNumbers
                     lret = PostMessage(pthWnd, WM_HSCROLL, SB_LINERIGHT, lhWnd)
                     i = i - 1
                 Loop
              End If
        End If
   End If
   
   EnumChildProc = bHook                              ' Continue enumerating the windows based on whether we are hooking or not
   
   ' It's possible that the addin has already been requested to unload and in such a case we will call free library on ourselves
   ' to reduce our ref count since we incremented it on our own so we can do a clean shutdown
   If Not bHook Then
        If Not FreeLibrary(hLib) Then
             Debug.Print "Unable to FreeLibrary: " & Err.Number & vbCrLf & Err.LastDllError
        End If
   End If
   
End Function

Function EnumThreadProc(ByVal lhWnd As Long, ByVal lParam As Long) _
   As Long
   Dim RetVal As Long
   Dim WinClassBuf As String * 255, WinTitleBuf As String * 255
   Dim WinClass As String, WinTitle As String

On Error GoTo Error

   RetVal = GetClassName(lhWnd, WinClassBuf, 255)
   WinClass = StripNulls(WinClassBuf)  ' remove extra Nulls & spaces
   RetVal = GetWindowText(lhWnd, WinTitleBuf, 255)
   WinTitle = StripNulls(WinTitleBuf)

   ' see the Windows Class and Title for top level Window
   Debug.Print "Thread Window Class = "; WinClass; ", Title = "; _
   WinTitle
   EnumThreadProc = True
   
   If InStr(1, WinTitle, "Microsoft Visual Basic") <> 0 _
    And WinClass = "wndclass_desked_gsk" _
    And MainWindowHwnd = 0 Then
    
    MainWindowHwnd = lhWnd
    ' Setup the windows Hook
    Hook
   
   End If
   
   Exit Function
Error:
    MsgBox Err.Description
   
End Function

Public Function StripNulls(OriginalStr As String) As String
   ' This removes the extra Nulls so String comparisons will work
   If (InStr(OriginalStr, Chr(0)) > 0) Then
      OriginalStr = Left(OriginalStr, InStr(OriginalStr, Chr(0)) - 1)
   End If
   StripNulls = OriginalStr
End Function

Public Function IsVerticalScrollBar(hWnd As Long) As Boolean

    ' Check the style of the window specified by hWnd to see if it's a vertical scrollbar

    Dim wi As WINDOWINFO
    wi.cbSize = Len(wi)
    
    If GetWindowInfo(hWnd, wi) Then
        If (wi.dwStyle And WS_VISIBLE) > 0 And (wi.dwStyle And SBS_VERT) > 0 Then
            IsVerticalScrollBar = True
            Exit Function
        End If
    End If
  
    IsVerticalScrollBar = False

End Function

Public Function IsHorizontalScrollBar(hWnd As Long) As Boolean

    ' Check the style of the window specified by hWnd to see if it's a horizontal scrollbar

    Dim wi As WINDOWINFO
    wi.cbSize = Len(wi)
    
    If GetWindowInfo(hWnd, wi) Then
        If (wi.dwStyle And WS_VISIBLE) > 0 And (wi.dwStyle And SBS_HORZ) > 0 Then
            IsHorizontalScrollBar = True
            Exit Function
        End If
    End If
  
    IsHorizontalScrollBar = False

End Function


Private Function QueryValue(sKeyName As String, sValueName As String) As Variant
    Dim lRetVal As Long         'result of the API functions
    Dim hKey As Long         'handle of opened key
    Dim vValue As Variant      'setting of queried value

    lRetVal = RegOpenKeyEx(HKEY_CLASSES_ROOT, sKeyName, 0, KEY_QUERY_VALUE, hKey)
    lRetVal = QueryValueEx(hKey, sValueName, vValue)
    RegCloseKey (hKey)
    
    QueryValue = vValue
End Function

Public Function SetValueEx(ByVal hKey As Long, sValueName As String, lType As Long, vValue As Variant) As Long
       Dim lValue As Long
       Dim sValue As String
       Select Case lType
           Case REG_SZ
               sValue = vValue & Chr$(0)
               SetValueEx = RegSetValueExString(hKey, sValueName, 0&, lType, sValue, Len(sValue))
           Case REG_DWORD
               lValue = vValue
               SetValueEx = RegSetValueExLong(hKey, sValueName, 0&, lType, lValue, 4)
           End Select
End Function

Function QueryValueEx(ByVal lhKey As Long, ByVal szValueName As String, vValue As Variant) As Long
       Dim cch As Long
       Dim lrc As Long
       Dim lType As Long
       Dim lValue As Long
       Dim sValue As String

       On Error GoTo QueryValueExError

       ' Determine the size and type of data to be read
       lrc = RegQueryValueExNULL(lhKey, szValueName, 0&, lType, 0&, cch)
       If lrc <> ERROR_NONE Then Error 5

       Select Case lType
           ' For strings
           Case REG_SZ:
               sValue = String(cch, 0)

   lrc = RegQueryValueExString(lhKey, szValueName, 0&, lType, _
   sValue, cch)
               If lrc = ERROR_NONE Then
                   vValue = Left$(sValue, cch - 1)
               Else
                   vValue = Empty
               End If
           ' For DWORDS
           Case REG_DWORD:
   lrc = RegQueryValueExLong(lhKey, szValueName, 0&, lType, _
   lValue, cch)
               If lrc = ERROR_NONE Then vValue = lValue
           Case Else
               'all other data types not supported
               lrc = -1
       End Select

QueryValueExExit:
       QueryValueEx = lrc
       Exit Function

QueryValueExError:
       Resume QueryValueExExit
End Function

Private Function LowWord(ByVal inDWord As Long) As Integer
    LowWord = inDWord And &H7FFF&
    If (inDWord And &H8000&) Then LowWord = LowWord Or &H8000
End Function

Private Function HighWord(ByVal inDWord As Long) As Integer
    HighWord = LowWord(((inDWord And &HFFFF0000) \ &H10000) And &HFFFF&)
End Function


저작자 표시 비영리 동일 조건 변경 허락
크리에이티브 커먼즈 라이선스
Creative Commons License
Posted by 벌커덕스
TAG VBA VB
프로그래밍2009/06/26 16:32
현재 개발중인 프로그램은 MFC 기반이 아니기 때문에 ActiveX Control을 사용하는 방법에 대한 기술자료 검색이 좀 어려웠다.
MFC로 되어있는 예제나 참고자료는 참 많이 널려있다.
그러던중 발견한것..


아주 심플하게 되어있어 사용하기 용이하다.

Screenshot - d.jpg

해당 사이트에 게시된 프로젝트는 VC2005로 만들어져있어 하위버전에서는 프로젝트 로드가 되지 않는다.

그냥 빈프로젝트를 생성하고 ax.cpp 와 ax.h 를 포함시키고

메인함수에서 아래의 함수를 호출해서 초기화하고 

    OleInitialize(0);
    if (!AXRegister())
        return 0;
    ...


리소스 스크립트에 다이얼로그 하위에 사용하고자하는 ActiveX의 클래스 아이디를 확인하여 삽입한다.

{
    CONTROL "{8856F961-340A-11D0-A96B-00C04FD705A2}", 801, "AX", 
                WS_CHILD | WS_VISIBLE, 0, 0, 500, 400
}

그다음에 실행시 SendMessage를 이용하여 해당 컨트롤의 포인터를 얻어올수 있다.

IWebBrowser2* wb = 0;
SendMessage(hX,AX_QUERYINTERFACE,(WPARAM)&IID_IWebBrowser2,(LPARAM)&wb);
if (wb)
{
    wb->Navigate(L"http://www.codeproject.com",0,0,0,0);
    wb->Release();
}


대략 이런 구조...

잘 동작한다.


저작자 표시 비영리 동일 조건 변경 허락
크리에이티브 커먼즈 라이선스
Creative Commons License
Posted by 벌커덕스
프로그래밍2009/06/25 01:20

요즘도 VB6을 사용하는 사람이 있는지는 모르겠지만 간단한 프로그램같은건 그냥 VB6으로 만드는게 훨씬 간편하다.

게다가 요즘나오는 윈도우에는 VB6 런타임 라이브러리가 내장되어있으니 그냥 exe파일만 있으면 그냥 돌아간다.

아!. 한국어판 VB를 사용하면 리소스파일인 vb6ko.dll을 찾는 경우가 있으니 영문판으로 빌드하면 그나마 vb6ko.dll도 찾지 않는다.

보통 VB는 고수준의 언어이기때문에 포인터(어드레스)를 쓸일이 거의 없긴하다.

그래도 간혹 윈도우 API와 같은걸 사용하다 보면 특정변수의 주소를 알아야할 필요가 생기기도 한다.

다음의 다섯가지형태로 주소를 알아낼수 있다.


--------------------------------------------------
VarPtr - 변수의 주소를 반환합니다.
VarPtrArray - 배열의 주소를 반환합니다.
StrPtr - 유니코드 문자열 버퍼의 주소를 반환합니다.
VarPtrStringArray - 주소의 문자열 배열 반환합니다.
ObjPtr - 개체 변수가 참조하는 인터페이스 포인터를 반환합니다.
----------------------------------------------------

자세한 내용은 마이크로소프트 홈페이지에서 찾을수 있다.


http://support.microsoft.com/kb/199824


요즘은 영문문서가 자동번역되어서 제공되는 모양이다. 위문서 상단에보면



메모리 주소 같은 변수에 대한 낮은 수준 정보를 얻기 위해 필요한 Visual Basic 프로그래머가 일반적이지 않은 것입니다. 그러나 이러한 정보가 필요로 하는 API 함수도 있습니다. 이 문서에서는 Visual Basic 프로그래머는 이 정보를 얻을 수 있도록 다음 Visual Basic 함수를 설명합니다.



라고 되어있는데 어쩐지 문맥이 좀 이상하다 싶었다.

어찌되었던 비베에서 어드레스를 넘길수 있다는사실..  


비베를 써봤던 사람은 다 알고 있을려나...



저작자 표시 비영리 동일 조건 변경 허락
크리에이티브 커먼즈 라이선스
Creative Commons License
Posted by 벌커덕스
프로그래밍2009/06/24 02:16

VB PCode Decompiler 2.5

 

이놈은 VB를 이용해서 만든 EXE파일의 정보를 볼수 있는 프로그램이다.

간단하게 사용해봐서 어떠한 기능들이 있는지 확인해보지 않았지만 프로젝트내의 오브젝트, 프로시저,

그리고 해당 프로시저의 옵셋등을 볼수가 있다..


스샷은 예전 네이버블로그에 올려둔걸 링크했다.


저작자 표시 비영리 동일 조건 변경 허락
크리에이티브 커먼즈 라이선스
Creative Commons License
Posted by 벌커덕스
한도 0

도깨비뉴스. http://www.dkbnews.com/?mn=news&mode=read&nidx=8262&dom=8...

Unity3D 일일 자동 빌드 하기

현재 프로젝트가 Unity3D를 이용하여 개발을 진행하다 보니 일일 자동 빌드의 필요성이 있어 해당 기능을 적용하였다. 우선 자동 빌드를 하기 위한 시스템에는 유니티 에디터가(빌더,컴파일러) 설치되어 있어야 한다. SCM은 S..

어쩌다가 찾아볼일 생기는 메인보드 비프음 판독하기

집에 컴퓨터가 많다보니 이런저런 수리할일이 생기는데 비프음가지고 장애유무를 판단해야한다. 그때마다 구글링하기도 불편하고.. 바이오스 종류별로 잘 정리해논 사이트가 있다. 이거하나면 비프음이 뭔뜻인지 알수 있다. http://w..

EXCEL VBA - 다른파일 스크립트 호출 및 종료

VBA코드의 재사용및 관리를 위하여 해당 데이터가 들어있는 엑셀에서는 비지니스 로직이 들어있는 코드를 생성하지 않는다. 하나의 엑셀파일에 모든 VBA코드를 작성/관리하고 데이터가 있는 엑셀파일에서 해당 기능을 호출하는 것. 이..

ER Studio Entity Name to Clipboard Sample Code

Sub Main Dim mdl As Model Dim ent As Entity Dim attr As AttributeObj Dim strResult As String Set mdl = DiagramManager.ActiveDi..

Unity3D 일일 자동 빌드 하기
스마트폰에 교통신용카드 이식하면 지갑이 필요없다.
스마트폰에 교통신용카드 이식하면 지갑이 필요없다.
스마트폰에 교통신용카드 이식하면 지갑이 필요없다.
스마트폰에 교통신용카드 이식하면 지갑이 필요없다.