PlaySound 함수는 파일 이름, 리소스, 또는 시스템 이벤트에 의해 명시된 소리를 재생한다. (시스템 이벤트는 레지스트리 또는 WIN.INI 파일에 있는 소리와 연관될 수 있다.)


문법


C++


BOOL PlaySound(

    LPCTSTR pszSound,

    HMODULE hmod,

    DWORD fdwSound

);


매개 변수


pszSound


재생할 소리를 지정하는 문자열. 최대 길이는 널 종료 포함 256 자 이다. 이 값이 NULL 이면 wave 형식의 소리 재생을 중지한다. wave 형식이 아닌 소리를 중지시키려면 fdwSound 매개 변수에 SND_PURGE 를 명시하라.


fdwSound 의 3개의 플래그 (SND_ALIAS, SND_FILENAME, 그리고 SND_RESOURCE) 는 이름이 시스템 이벤트, 파일 이름, 또는 리소스 식별자중 어떤 것인지를 결정한다. 이 플래그들이 명시되지 않으면, PlaySound 는 레지스트리 또는 WIN.INI 파일에서 명시된 소리 이름과 연관된 것을 검색한다. 연관된 것이 검색되면, 소리 이벤트가 재생된다. 레지스트리에 관련된 것이 없다면, 파일 이름으로 해석한다.


hmod


읽을 수 있는 리소스를 포함한 실행가능한 파일에 대한 핸들. fdwSound 에 SND_RESOURCE 가 명시되지 않은한 NULL 이어야 한다.


fdwSound


소리 재생에 관한 플래그. 다음 값들이 정의되어있다.


 값

의미 

 SND_APPLICATION

 pszSound 매개 변수는 레지스트리에 있는 응용프로그램 별 별칭이다. 이 플래그는 응용프로그램에 정의된 소리 별칭을 명시하기 위해 SND_ALIAS 또는 SND_ALIAS_ID 플래그와 결합해서 사용할 수 있다.

 SND_ALIAS

 pszSound 매개 변수는 레지스트리 또는 WIN.INI 파일에 있는 시스템 이벤트 별칭이다. SND_FILENAME 또는 SND_RESOURCE 와 함께 사용하지 말라.

 SND_ALIAS_ID

 pszSound 매개 변수는 시스템 이벤트 별칭을 위해 미리 정의된 식별자이다. 아래 주의를 보라.

 SND_ASYNC

 소리는 비동기적으로 재생되고 소리 시작 이후 PlaySound 는 즉시 반환된다. 비동기 적으로 재생되는 wave 형식의 소리를 중지시키려면, pszSound 를 NULL 로 설정하여 PlaySound 를 호출하라.

 SND_FILENAME

 pszSound 매개 변수는 파일 이름이다. 파일을 찾을 수 없다면, SND_NODEFAULT 플래그가 설정되어 있지 않는한 기본 소리를 재생한다.

 SND_LOOP

 pszSound 를 NULL 로 설정하여 PlaySound 를 다시 호출되기 전까지 소리를 반복 재생한다. 이 플래그와 함께 SND_ASYNC 플래그를 설정해야 한다.

 SND_MEMORY

 pszSound 매개 변수는 메모리에 읽혀진 소리를 가리킨다. 자세한 정보는 Playing WAVE Resources 를 보라.

 SND_NODEFAULT

 기본 소리 이벤트를 사용하지 않는다. 소리를 찾을 수 없으면, PlaySound 는 기본 소리 재생없이 조용히 반환한다.

 SND_NOSTOP

 명시된 소리 이벤트는 동일한 프로세스에서 이미 재생중인 다른 소리 이벤트에게 양보한다. 소리를 발생시키는데 필요한 자원이 다른 소리를 재생하는데 사용되어 소리를 재생할 수 없다면, 이 함수는 요청된 소리를 재생하지않고 즉시 FALSE 를 반환한다


 이 플래그가 설정되지 않으면, PlaySound 는 같은 프로세스에서 현재 재생중인 소리를 중지하려한다. 다른 프로세스의 소리 재생에는 영향을 미치지 않는다.

 SND_NOWAIT

 지원되지 않음.


 주석 이전 버전의 문서에서는 이 플래그가 지원된다고 잘못 명시되었다. 이 함수는 이 플래그를 무시한다.

 SND_PURGE

 지원되지 않음.

 SND_RESOURCE

 pszSound 매개 변수는 리소스 식별자이다; hmod 는 리소스를 포함하는 인스턴스를 명시해야한다. 자세한 정보를 Playing WAVE Resources 를 보라.

 SND_SENTRY

 주석 Windows Vista 또는 그 이상이 필요하다.


 이 플래그가 설정되있으면, 함수는 소리가 재생될 때 SoundSentry 이벤트를 발생시킨다.


 SoundSentry 는 소리가 재생될 때 컴퓨터가 시각적 신호를 표시하는 접근성 기능이다. 사용자가 SoundSentry 를 활성화하지 않았다면, 시각적 신호는 표시되지 않는다.

 SND_SYNC

 소리가 동기적으로 재생되고, PlaySound 는 소리 이벤트 완료 이후 반환된다. 기본 동작이다.

 SND_SYSTEM

 주석 Windows Vista 또는 그 이상이 필요하다.


 이 플래그가 설정되면, 소리는 시스템 알림 소리를 위한 오디오 세션에 할당된다. 시스템 음량제어 프로그램 (SndVol) 은 시스템 알림 소리를 제어하는 음량 슬라이더를 표시한다. 이 플래그를 설정하는 것은 소리를 이 음량 슬라이더 아래에 놓는다.


 이 플래그가 설정되지 않으면, 소리는 응용프로그램의 처리를 위한 기본 오디오 세션에 할당된다.


 자세한 정보는 Core Audio APIs 문서를 보라.


반환 값


성공하면 TRUE 를 그외는 FALSE 를 반환한다.


주의


pszSound 에 명시된 소리는 사용 물리 메모리에 맞아야 하고 설치된 wave 형식 오디오 장치 드라이버에서 재생가능해야한다.


PlaySound 는 소리 파일을 위해 다름 경로를 검색한다; 현재 디렉토리; Windows 디렉토리; Windows 시스템 디렉토리; 환경 변수 PATH 에 나열된 디렉토리들; 그리고 네트워크에 매핑된 디렉토리 목록. 명시된 소리를 찾지 못하고 SND_NODEFAULT 플래그가 명시되지 않았다면, PlaySound 는 기본 시스템 이벤트 소리를 대신 사용한다. 시스템 기본 엔트리와 기본 소리를 찾을 수 없으면, 아무 소리도 재생하지 않고 FALSE 를 반환한다.


fdwSound 에 SND_ALIAS_ID 플래그가 명시되있다면, pszSound 매개 변수는 다음 값 중 하나여야 한다.


 값

 설명

 SND_ALIAS_SYSTEMASTERISK

 "SystemAsterisk" 이벤트.

 SND_ALIAS_SYSTEMDEFAULT

 "SystemDefault" 이벤트.

 SND_ALIAS_SYSTEMEXCLAMATION

 "SystemExclamation" 이벤트.

 SND_ALIAS_SYSTEMEXIT

 "SystemExit" 이벤트.

 SND_ALIAS_SYSTEMHAND

 "SystemHand" 이벤트.

 SND_ALIAS_SYSTEMQUESTION

 "SystemQuestion" 이벤트.

 SND_ALIAS_SYSTEMSTART

 "SystemStart" 이벤트.

 SND_ALIAS_SYSTEMWELCOME

 "SystemWelcome" 이벤트.


SND_ASYNC 플래그는 PlaySound 가 소리 재생 완료를 기다리지 않고 즉시 반환하게 한다. SND_MEMORY 와 SND_ASYNC 를 결합하여 사용할 경우, 소리를 담고있는 메모리 버퍼는 소리 재생이 완료될때까지 유효해야한다.


예제


다음 예제는 소리 파일을 재생한다:


C++


PlaySound(TEXT("recycle.wav"), NULL, SND_FILENAME);


다음 예제는 소리파일 리소스를 재생한다:


C++


PlaySound(

    MAKEINTRESOURCE(IDR_WAVE1),

    GetModuleHandle(NULL),

    SND_RESOURCE);


다음 예제는 시스템 이벤트 소리를 재생한다:


C++


PlaySound(TEXT("SystemStart"), NULL, SND_ALIAS);


다음 예제는 이전 예제와 동일하나, 시스템 이벤트 식별자를 사용한다:


C++


PlaySound((LPCTSTR)SND_ALIAS_SYSTEMSTART, NULL, SND_ALIAS_ID);


다음 예제는 레지스트리에 있는 응용프로그램 정의된 소리를 재생한다:


C++


PlaySound(TEXT("MyAppSound"), NULL, SND_ALIAS | SND_APPLICATION);


다음 예제는 비동기 재생중인 소리를 중지시킨다:


C++


PlaySound(NULL, 0, 0);



요구사항


 클라이언트 최소 사양

 Windows 2000 Professional [데스크탑 앱 전용]

 서버 최소 사양

 Windows 2000 Server [데스크탑 앱 전용]

 Header

 Mmsystem.h (include Windows.h)

 Library

 Winmm.lib

 DLL

 Winmm.dll

 유니코드와 ANSI 명칭

 PlaySoundW (유니코드) and PlaySoundA (ANSI)


그 외 볼것


Waveform Audio

Waveform Functions



uses

  Winapi.ImageHlp, Winapi.Windows;


function GetDLLExports(const AFileName: AnsiString; AList: TStrings): Boolean;

var

  Image: LoadedImage;

  pExport: PImageExportDirectory;

  pNames: PDWORD;

  Dummy: DWORD;

  I: DWORD;

begin

  Result := MapAndLoad(PAnsiChar(AFileName), nil, @Image, True, True);

  if Result then begin

    try

      pExport := ImageDirectoryEntryToData(Image.MappedAddress, False, IMAGE_DIRECTORY_ENTRY_EXPORT, ULONG(Dummy));

      if pExport <> nil then begin

        pNames := ImageRvaToVa(Image.FileHeader, Image.MappedAddress, pExport^.AddressOfNames, Pointer(Dummy));

        for I := 0 to Pred(pExport^.NumberOfNames) do begin

          AList.Add(String(PAnsiChar(ImageRvaToVa(Image.FileHeader, Image.MappedAddress, pNames^, Pointer(Dummy)))));

          Inc(pNames);

        end;

      end else begin

        Result := False;

      end;

    finally

      UnMapAndLoad(@Image);

    end;

  end;

end;


문자열이 화면에 표시될때의 가로폭은 TCanvas.TextWidth 를 이용하여 확인된다.


1. 문자열이 원하는 길이보다 크면 문자열 뒤에 말줄임표 추가

2. 문자열이 원하는 길이보다 길지 않을 때까지, 말줄임표 앞 1글자를 삭제

3. 말줄임표 앞 1글자가 2바이트 문자의 앞(Lead) 문자일 경우 삭제


AnsiString __fastcall TextEllipsis(TCanvas *C, AnsiString V, int W, const AnsiString &P = "...")

{

for (C->TextWidth(V) > W? V += P: V; V.Length() > 0 && C->TextWidth(V) > W; V.Delete(V.Length() - P.Length(), 1));

if (ByteType(V, V.Length() - P.Length()) == mbLeadByte) {

V.Delete(V.Length() - P.Length(), 1);

}

return V;

}


'Windows > RAD Studio' 카테고리의 다른 글

DLL Export 함수 목록 가져오기  (0) 2015.10.07
[CB] Ole - InternetExplorer 띄우기  (0) 2015.09.17
프로세스 종료  (0) 2015.09.08
DLL 기본 주석 문구 해석  (0) 2015.05.13
[Del] TListBox HorizontalScrollBar 표시  (0) 2015.05.06

신기하지만 위험을 감수하며 쓸 필요없는 방법.


char (&ArrayReturnFunc(int AValue))[10]

{

static __thread char result[10];

memset(result, 0, 10);

std::snprintf(result, 10, "Test %d", AValue);

return result;

}


배열의 크기를 미리 define 하여 사용하는 것은 좀 너저분하다.


sizeof(array) / sizeof(array[0]) 을 이용하여도 되지만, 이것은 배열이 아닌 포인터에도 코드가 돌아가며 오동작을 할 수 있다.


다음은 template 을 이용하여 컴파일러가 컴파일 할 때

같은 개수의 char 배열을 반환하는 형태의 내용없는 함수를 만들어 (반환값이 중요한게 아니라 내용이 없어도 된다.)

sizeof 를 수행하는 방식으로 개수를 알아내는 코드이다.

포인터에 사용하면 컴파일 오류가 날 것이다.


template <typename T, size_t S>

char (&ArraySizeHelper(T (&)[S]))[S];

#define countof(A) (sizeof(ArraySizeHelper(A)))


다른 속성과 함수는 ActiveX Control Test Container 같은 프로그램으로 확인하자.


#include <System.Win.Comobj.hpp>


Variant IE = System::Win::Comobj::CreateOleObject("InternetExplorer.Application");
IE.OleProcedure("Navigate2", WideString("http://google.com/"));
IE.OlePropertySet("ToolBar", false);
IE.OlePropertySet("AddressBar", true);
IE.OlePropertySet("Left", 0);
IE.OlePropertySet("Top", 0);
IE.OlePropertySet("Width", 640);
IE.OlePropertySet("Height", 480);
IE.OlePropertySet("Visible", true);
IE = Unassigned;


외부 프로세스를 강제로 종료하는 간단한 방법.

taskkill 커맨드를 이용하는 것이다.


::ShellExecute(NULL, L"runas", L"taskkill", String().sprintf(L"/pid %d /f", dwProcessId).c_str(), NULL, SW_HIDE);


이 코드를 실행하는 프로그램이 관리자 권한이 없을경우 "프로세스종료" 라는 내용의 권한 획득 창이 뜬다.


정상적인 종료를 시키려는 경우 복잡한 코드를 작성하고,

해당 프로그램의 동작은 신경쓰지 않고 무조건 죽이려 한다면 이렇게 하면 간단하다.


요약

1. export 된 함수 매개변수 또는 결과값으로 String 또는 String 을 포함하는 구조체/클래스 를 사용하는 경우

   DLL 과 DLL 을 사용하는 프로젝트에 MEMMGR.LIB 를 추가하라.

2. DLL 에서 export 된 TObject 에서 상속되지 않은 클래스를 new/delete 하는 경우 프로젝트에 MEMMGR.LIB 를 추가하라.

3. MEMMGR.LIB 를 추가하면 BORLNDMM.DLL 을 사용하게되므로 같이 배포해야 한다.

4. 이를 피하려면 "char*" 또는 ShortString 을 사용하라.

5. 동적 RTL 을 사용하는 경우에는 암시적으로 처리가 되므로 신경쓰지 않아도 된다.


원본


//   Important note about DLL memory management when your DLL uses the

//   static version of the RunTime Library:

//

//   If your DLL exports any functions that pass String objects (or structs/

//   classes containing nested Strings) as parameter or function results,

//   you will need to add the library MEMMGR.LIB to both the DLL project and

//   any other projects that use the DLL.  You will also need to use MEMMGR.LIB

//   if any other projects which use the DLL will be performing new or delete

//   operations on any non-TObject-derived classes which are exported from the

//   DLL. Adding MEMMGR.LIB to your project will change the DLL and its calling

//   EXE's to use the BORLNDMM.DLL as their memory manager.  In these cases,

//   the file BORLNDMM.DLL should be deployed along with your DLL.

//

//   To avoid using BORLNDMM.DLL, pass string information using "char *" or

//   ShortString parameters.

//

//   If your DLL uses the dynamic version of the RTL, you do not need to

//   explicitly add MEMMGR.LIB as this will be done implicitly for you


해석


//   정적 Runtime library 를 사용하는 DLL 메모리 관리에 관한 중요 사항:

//

//   DLL 이 매개변수 또는 반환 값으로 String 객체 (또는 String 을 포함하는

//   구조체/클래스) 를 전달하는 경우, MEMMGR.LIB 를 DLL 프로젝트와 DLL 을

//   사용하는 다른 프로젝트에 추가하여야 한다. 또한 DLL 을 사용하는 프로젝트가

//   DLL 에서 export 된 TObject 에서 상속받지 않은 클래스를 new 또는 delete

//   하는 경우 MEMMGR.LIB 를 추가해야 한다. MEMMGR.LIB 를 프로젝트에 추가하면

//   DLL 과 그것을 호출하는 EXE 의 메모리 관리자를 BORLNDMM.DLL 로 변경됩니다.

//   이경우, BORLNDMM.DLL 은 당신의 DLL 과 함께 배포해야 합니다.

//

//   BORLNDMM.DLL 사용을 피하기위해, "char *" 또는 ShortString 매개 변수로

//   문자열 정보를 전달하시오.

//

//   동적 RTL 을 사용할 경우, MEMMGR.LIB 가 암시적으로 추가되므로 이를

//   명시할 필요가 없다.


'Windows > RAD Studio' 카테고리의 다른 글

[CB] Ole - InternetExplorer 띄우기  (0) 2015.09.17
프로세스 종료  (0) 2015.09.08
[Del] TListBox HorizontalScrollBar 표시  (0) 2015.05.06
[Win32] 메모리 사용량 확인  (0) 2015.05.06
[C++, Win32] Thread safe FreeAndNil  (0) 2015.04.28



TListBox 를 사용하는 코드 전에 TListBox 의 type 을 재정의 해준다.


http://tinydew4.tistory.com/77 의 자동화 버전



uses

  Vcl.StdCtrls;


type

  TListBox = class(Vcl.StdCtrls.TListBox)

  private

    FMaxWidth: Integer;

  protected

    procedure WndProc(var Message: TMessage); override;

  end;


implementation


procedure TListBox.WndProc(var Message: TMessage);

var

  iTextWidth: Integer;


  procedure ItemAdded(AValue: PChar);

  begin

    iTextWidth := Canvas.TextWidth(AValue);

    if iTextWidth > FMaxWidth then begin

      InterlockedExchange(FMaxWidth, iTextWidth);

      Perform(LB_SETHORIZONTALEXTENT, FMaxWidth + 2, 0);

    end;

  end;

  procedure ItemDeleted(AItemIndex: Integer);

  var

    iMaxWidth: Integer;

    I: Integer;

  begin

    if (0 > AItemIndex) or (AItemIndex >= Items.Count) then

      Exit;


    iTextWidth := Canvas.TextWidth(Items.Strings[AItemIndex]);

    if iTextWidth < FMaxWidth then

      Exit;


    iMaxWidth := 0;

    for I := 0 to Pred(Items.Count) do begin

      if I <> AItemIndex then begin

        iTextWidth := Canvas.TextWidth(Items.Strings[I]);

        if iTextWidth > iMaxWidth then

          iMaxWidth := iTextWidth;

      end;

    end;


    if iMaxWidth <> FMaxWidth then begin

      InterlockedExchange(FMaxWidth, iMaxWidth);

      Perform(LB_SETHORIZONTALEXTENT, FMaxWidth + 2, 0);

    end;

  end;

begin

  if (Message.Msg = LB_ADDSTRING) or (Message.Msg = LB_INSERTSTRING) then begin

    ItemAdded(PChar(Message.LParam));

  end else if Message.Msg = LB_DELETESTRING then begin

    ItemDeleted(Message.WParam);

  end else if Message.Msg = WM_CREATE then begin

    InterlockedExchange(FMaxWidth, 0);

  end;


  inherited;

end;


GlobalMemoryStatusEx, TMemoryStatusEx


(GlobalMemoryStatus, TMemoryStatus - 4GB 의 한계가 있다.)


+ Recent posts