두 함수의 기능

=> 메시지는 주로 사용자에 의해 발생되지만 프로그램 내부에서 윈도우간의 통신을
위해 의도적으로 다른 윈도우에게 메시지를 보낼 수도 있다. 이때는 다음 두 함수를 
사용한다.

BOOL PostMessage( HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam );
LRESULT SendMessage( HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam );

두 함수의 인수가 완전히 동일하다. 여기서 Post 라는 말은 우리말로 "붙인다"라고
번역하며 Send 라는 말은 "보낸다"라고 번역한다.




★ PostMessage 함수


PostMessage 함수는 Msg 인수로 지정된 메시지를 hWnd 윈도우의 메시지 큐에 집어넣어

윈도우 프로시저에서 이 메시지를 처리하도록 한다. 메시지를 메시지 큐에 넣어 놓기만

하고 곧바로 리턴하므로 메시지는 곧바로 처리되지 않는다. 큐에 붙여진 메시지는

GetMessage 에 의해 읽혀지고 DispatchMessage 에 의해 윈도우 프로시저로 보내져

처리될 것이다.



급하게 처리될 필요가 없거나 또는 지금 하고 있는 작업을 완전히 끝내야만 처리할

수 있는 메시지는 PostMessage 함수로 큐에 붙인다. 이 함수로 붙여진 메시지는

언제 처리될지 정확하게 예측하기 힘들다. 그래서 붙여지는 메시지의 wParam 과

lParam 에는 지역 포인터를 사용하지 않아야 한다. 메시지를 붙일 시점에는

포인터가 존재했더라도 메시지가 처리될 시점에는 포인터가 무효해질 수 있기

때문이다.


PostMessage 는 메시지를 큐에 붙인 후 성공하면 TRUE 를 리턴하며 실패하면

FALSE 를 리턴하는데 이 리턴값은 가급적이면 점검해보는 것이 좋다. 왜냐하면

메시지 큐는 크기가 한정되어 있기 때문에 고속으로 전송되는 모든 메시지를

다 수용하지 못할 수도 있기 때문이다.



PostMessage 의 첫번째 인수인 hWnd 는 이 메시지를 받을 윈도우의 핸들인데 이값은

아주 특수하게 NULL 일 수도 있다. 즉, 메시지를 받는 대상 윈도우가 없는 메시지를

큐에 붙일 수도 있는데 이런 메시지는 특정 윈도우에게 신호를 보내기 위한 것이

아니라 응용 프로그램 전반에 걸친 작업 지시를 보낼때 사용된다. 대상 윈도우가

없기 때문에 이 메시지는 윈도우 프로시저가 처리할 수 없으며 반드시 메시지 루프에서

직접 처리해주어야 한다.



while(GetMessage(&Message, 0, 0, 0) {
if (Message.message == WM_SOME ) {
// 직접 처리
} else {
TranslateMessage( &Message );
DispatchMessage( &Message );
}
}



GetMessage 로 메시지를 꺼낸 후 곧바로 메시지 ID 를 비교해보고 스레드를 위한

메시지인지 검사해본다. 만약 스레드를 위한 메시지라면 메시지 루프에서

직접 처리해야 하며 DispatchMessage 함수로 보내서는 안된다. 대상 윈도우가

지정되지 않은 메시지이기 때문에 이 메시지를 받아줄 윈도우 프로시저가 없기

때문이다. PostMessage 함수가 메시지를 붙여넣는 큐가 윈도우를 위한 큐가 아니라

스레드를 위한 큐이기 때문에 이런 기법이 가능하다. 다른 스레드의 메시지 큐에

메시지를 붙일 때는 다음 함수가 사용된다.



BOOL PostThreadMessage ( DWORD idThread, UINT Msg, WPARAM wParam, LPARAM lParam );



윈도우 핸들 대신 스레드의 ID를 첫 번째 인수로 지정해준다. 이때 이 메시지를 받을

스레드는 반드시 스레드 큐를 가지고 있어야 하는데 큐를 가지지 않는

작업 스레드(Worker Thread)는 메시지를 받지 못한다.






★ SendMessage 함수

메시지를 큐에 넣는 것이 아니라 곧바로 윈도우 프로시저로 보내 즉각 처리하도록

하며 메시지가 완전히 처리되기 전에는 리턴하지 않는다. 즉 블록시킨다. 그래서

SendMessage는 윈도우간, 특히 부모 윈도우와 차일드 컨트롤간의 통신에 자주 사용된다.






         PostMessage     SendMessage
        ↙            ↙
┏━┓    ┏━┓ 메시지루프    ↙
┃ ┃------→┃ ┃-------------→ WndProc
┃ ┃    ┃ ┃
┃ ┃    ┃ ┃
┗━┛    ┗━┛
시스템    스레드
메시지큐   메시지큐






질문2) 함수명앞의 LRESULT , BOOL 의 선언은 function 의 리턴예약어 Result 와 Boolean 명칭하는건가요?

=> BOOL 은 델파이에서의 Boolean 과 같습니다.


그러나, LRESULT 는 Result 와는 다릅니다.

LRESULT 는 Win32 API 에서 쓰이는 리턴값의 한 종류입니다.

Result 는 델파이에서 function 의 마지막에 사용되는 C언어로 따지자면 return 예약어와 같은 것입니다.


원본 링크 : http://blog.daum.net/magixtech/1906578




uses

  ComObj;

var

  ExcelApp: OleVariant;

implementation


procedure TForm1.Button1Click(Sender: TObject);

const

  // SheetType

  xlChart = -4109;

  xlWorksheet = -4167;

  // WBATemplate

  xlWBATWorksheet = -4167;

  xlWBATChart = -4109;

  // Page Setup

  xlPortrait = 1;

  xlLandscape = 2;

  xlPaperA4 = 9;

  // Format Cells

  xlBottom = -4107;

  xlLeft = -4131;

  xlRight = -4152;

  xlTop = -4160;

  // Text Alignment

  xlHAlignCenter = -4108;

  xlVAlignCenter = -4108;

  // Cell Borders

  xlThick = 4;

  xlThin = 2;

var

  ColumnRange: OleVariant;

  // Function to get the number of Rows in a Certain column

  function GetLastLine(AColumn: Integer): Integer;

  const

    xlUp = 3;

  begin

    Result := ExcelApp.Range[Char(96 + AColumn) + IntToStr(65536)].end[xlUp].Rows.Row;

  end;

begin

  { Start Excel }

  // By using GetActiveOleObject, you use an instance of Word that's already running,

  // if there is one.

  try

    ExcelApp := GetActiveOleObject('Excel.Application');

  except

    try

      ExcelApp := GetActiveOleObject('scalc.Application');

    except  

      try

        // If no instance of Word is running, try to Create a new Excel Object

        ExcelApp := CreateOleObject('Excel.Application');  

      except

        try

          // If no instance of Word is running, try to Create a new scalc Object

          ExcelApp := CreateOleObject('scalc.Application');  

        except

          ShowMessage('Cannot start Excel/Excel not installed ?');

          Exit;

        end;                

      end;    

    end;

  end;

  // Add a new Workbook, Neue Arbeitsmappe offnen

  ExcelApp.Workbooks.Add(xlWBatWorkSheet);

  // Open a Workbook, Arbeitsmappe offnen

  ExcelApp.Workbooks.Open('c:\YourFileName.xls');


  // Rename the active Sheet

  ExcelApp.ActiveSheet.Name := 'This is Sheet 1';

  // Rename

  ExcelApp.Workbooks[1].WorkSheets[1].Name := 'This is Sheet 1';

  // Insert some Text in some Cells[Row,Col]

  ExcelApp.Cells[1, 1].Value := 'SwissDelphiCenter.ch';

  ExcelApp.Cells[2, 1].Value := 'http://www.swissdelphicenter.ch';

  ExcelApp.Cells[3, 1].Value := FormatDateTime('dd-mmm-yyyy', Now);

  // Setting a row of data with one call

  ExcelApp.Range['A2', 'D2'].Value := VarArrayOf([1, 10, 100, 1000]);

  // Setting a formula

  ExcelApp.Range['A11', 'A11'].Formula := '=Sum(A1:A10)';

  // Change Cell Alignement

  ExcelApp.Cells[2, 1].HorizontalAlignment := xlright;

  // Change the Column Width.

  ColumnRange := ExcelApp.Workbooks[1].WorkSheets[1].Columns;

  ColumnRange.Columns[1].ColumnWidth := 20;

  ColumnRange.Columns[2].ColumnWidth := 40;

  // Change Rowheight / Zeilenhohe andern:

  ExcelApp.Rows[1].RowHeight := 15.75;

  // Merge cells, Zellen verbinden:

  ExcelApp.Range['B3:D3'].Mergecells := True;

  // Apply borders to cells, Zellen umrahmen:

  ExcelApp.Range['A14:M14'].Borders.Weight := xlThick; // Think line/ Dicke Linie

  ExcelApp.Range['A14:M14'].Borders.Weight := xlThin;  // Thin line Dunne Linie

  // Set Bold Font in cells, Fettdruck in den Zellen

  ExcelApp.Range['B16:M26'].Font.Bold := True;

  // Set Font Size, Schriftgroße setzen

  ExcelApp.Range['B16:M26'].Font.Size := 12;

  //right-aligned Text, rechtsbundige Textausrichtung

  ExcelApp.Cells[9, 6].HorizontalAlignment := xlright;

  // horizontal-aligned text, horizontale Zentrierung

  ExcelApp.Range['B14:M26'].HorizontalAlignment := xlHAlignCenter;

  // left-aligned Text, vertikale Zentrierung

  ExcelApp.Range['B14:M26'].VerticallyAlignment := xlVAlignCenter;


  { Page Setup }

  ExcelApp.ActiveSheet.PageSetup.Orientation := xlLandscape;

  // Left, Right Margin (Seitenrander)

  ExcelApp.ActiveSheet.PageSetup.LeftMargin  := 35;

  ExcelApp.ActiveSheet.PageSetup.RightMargin := -15;

  // Set Footer Margin

  ExcelApp.ActiveSheet.PageSetup.FooterMargin := ExcelApp.InchesToPoints(0);

  // Fit to X page(s) wide by Y tall

  ExcelApp.ActiveSheet.PageSetup.FitToPagesWide := 1;  // Y

  ExcelApp.ActiveSheet.PageSetup.FitToPagesTall := 3; // Y

  // Zoom

  ExcelApp.ActiveSheet.PageSetup.Zoom := 95;

  // Set Paper Size:

  ExcelApp.PageSetup.PaperSize := xlPaperA4;

  // Show/Hide Gridlines:

  ExcelApp.ActiveWindow.DisplayGridlines := False;

  // Set Black & White

  ExcelApp.ActiveSheet.PageSetup.BlackAndWhite := False;

  // footers

  ExcelApp.ActiveSheet.PageSetup.RightFooter := 'Right Footer / Rechte Fußzeile';

  ExcelApp.ActiveSheet.PageSetup.LeftFooter  := 'Left Footer / Linke Fußzeile';

  // Show Excel Version:

  ShowMessage(Format('Excel Version %s: ', [ExcelApp.Version]));

  // Show Excel:

  ExcelApp.Visible := True;

  // Save the Workbook

  ExcelApp.SaveAs('c:\filename.xls');

  // Save the active Workbook:

  ExcelApp.ActiveWorkBook.SaveAs('c:\filename.xls');

end;

procedure TForm1.FormDestroy(Sender: TObject);

begin

  // Quit Excel

  if not VarIsEmpty(ExcelApp) then

  begin

    ExcelApp.DisplayAlerts := False;  // Discard unsaved files....

    ExcelApp.Quit;

  end;

end;


원본 링크 : http://seniorkr.tistory.com/41


선그리기 참고 


procedure TForm1.Button1Click(Sender: TObject);
var
  Excel: OleVariant;
  WorkBook: OleVariant;
  WorkSheet: OleVariant;

  i : integer;

Const
  xlNone = -4142;
  xlDiagonalDown = 5;
  xlDiagonalUp = 6;
  xlEdgeLeft = 7;
  xlEdgeTop = 8;
  xlEdgeBottom = 9;
  xlEdgeRight = 10;
  xlContinuous = 1;

  xlThin = 2;
  xlThick = 4;

  xlAutomatic = -4105;

begin

  Excel := CreateOleObject('Excel.Application');
  Excel.Visible := True;

  // 워크북 추가
  Excel.WorkBooks.Add;
  WorkBook := Excel.ActiveWorkBook;

  // 워크시트 추가
  Workbook.sheets.add;

  // 작업할  워크시트 선택
  WorkSheet := WorkBook.WorkSheets[1];

  // 선그리기
  WorkSheet.Range['B5:E10'].Borders[xlDiagonalDown].LineStyle := xlNone;
  WorkSheet.Range['B5:E10'].Borders[xlDiagonalUp].LineStyle := xlNone;
  WorkSheet.Range['B5:E10'].Borders[xlEdgeLeft].LineStyle := xlContinuous;
  WorkSheet.Range['B5:E10'].Borders[xlEdgeTop].LineStyle := xlContinuous;
  WorkSheet.Range['B5:E10'].Borders[xlEdgeBottom].LineStyle := xlContinuous;
  WorkSheet.Range['B5:E10'].Borders[xlEdgeBottom].Weight := xlThick;
  WorkSheet.Range['B5:E10'].Borders[xlEdgeBottom].ColorIndex := xlAutomatic;
  WorkSheet.Range['B5:E10'].Borders[xlEdgeRight].LineStyle := xlContinuous;

end;


원본 : http://wwwi.tistory.com/174


참고

http://skql.tistory.com/11

http://www.nika-soft.com/nativeexcel2/doc/brd_pls.htm



실제 적용 소스


//엑셀파일로 저장하기

procedure TfN040070_1.Btn_SaveClick(Sender: TObject);

var

  vHandle : THandle;

  vExcel  : Variant;

  vSheet  : Variant;

  Range   : Variant;

  i       : integer;

Const

  xlCenter = -4108;

  xlRight = -4152;

  xlNone = -4142;

  xlDiagonalDown = 5;

  xlDiagonalUp = 6;

  xlEdgeLeft = 7;

  xlEdgeTop = 8;

  xlEdgeBottom = 9;

  xlEdgeRight = 10;

  xlContinuous = 1;


  xlThin = 2;

  xlThick = 4;


  xlAutomatic = -4105;


begin

  vHandle := FindWindow('XLMAIN',nil);

  if vHandle <> 0 then vExcel := GetActiveOLEObject('Excel.Application')

  else

  begin

    try

      vExcel := CreateOLEObject('Excel.Application');

    except

      Application.MessageBox('Excel을 열 수 없습니다.'+ char(13) +

                             'Excel이 설치되어 있는지 확인하세요!',

                             '정보', MB_OK);

    end;

  end;


  //엑셀객체 정의

  vExcel.Visible := True;                                      


  SetForegroundWindow(vHandle);

  vExcel.WorkBooks.Add;

  vExcel.WorkBooks[vExcel.WorkBooks.Count].WorkSheets[1].Name := Caption;

  vSheet := vExcel.WorkBooks[vExcel.WorkBooks.Count].WorkSheets[Caption];


  //컬럼, 로우 사이즈 변경

  vSheet.Columns[1].ColumnWidth := 35;

  vSheet.Columns[2].ColumnWidth := 20;

  vSheet.Columns[3].ColumnWidth := 10;

  vSheet.Columns[4].ColumnWidth := 25;


  vExcel.Rows[1].RowHeight := 8;

  vExcel.Rows[4].RowHeight := 8;


  //해더 설정

  vSheet.Cells[2,1].Value := 'TEST1'; vSheet.Cells[2,2].Value := Trim(B_1.Caption);

  vSheet.Cells[2,3].Value := 'TEST2'; vSheet.Cells[2,4].Value := Trim(B_2.Caption);

  vSheet.Range['A2:D2'].Borders.LineStyle := xlContinuous;


  vSheet.Cells[3,1].Value := 'TEST3'; vSheet.Cells[3,2].Value := Trim(B_3.Caption);

  vSheet.Cells[3,3].Value := 'TEST4;  vSheet.Cells[3,4].Value := Trim(B_4.Caption);

  vSheet.Range['A3:D3'].Borders.LineStyle := xlContinuous;


  //데이터 설정

  for i:= 0 to ed_contents.Lines.Count -1 do begin

    //데이터 치환_ 메모장에서 한줄씩 치환

    vSheet.Cells[5+i,1].Value := ed_contents.Lines.Strings[i];


    //테두리 라인 그리기

    vSheet.Range['A'+IntToStr(5+i)].Borders[xlEdgeLeft].LineStyle := xlContinuous; //왼쪽 라인 그리기

    vSheet.Range['D'+IntToStr(5+i)].Borders[xlEdgeRight].LineStyle:= xlContinuous; //오른쪽 라인 그리기


    if i = 0 then //첫번째줄

      vSheet.Range['A'+IntToStr(5+i), 'D'+IntToStr(5+i)].Borders[xlEdgeTop].LineStyle := xlContinuous //윗쪽 라인 그리기

    else if i = ed_contents.Lines.Count -1 then //마지막줄

      vSheet.Range['A'+IntToStr(5+i), 'D'+IntToStr(5+i)].Borders[xlEdgeBottom].LineStyle := xlContinuous; //아랫쪽 라인 그리기

  end;


  //눈금자 안보이게 설정

  vExcel.ActiveWindow.DisplayGridlines := False;

end;

단축키
설명
Win + UP Arrow현재 창을 최대화.

Win + Down Arrow

현재 창을 최대화에서 복원 하거나 최소화.
Win + Left Arrow현재창을 왼쪽으로 붙임.
Win + Right Arrrow현재창을 오른쪽으로 붙임.
Win + [number]타스크바에 있는 프로그램을 활성화 하거나 실행. 실행중인 프로그램은 영향을 받지 않음.
Win + Home현재창의 제외한 창을 최소화.
Win + Space전체창을 투명화 해서 바탕화면을 봄.
Win + Pause/Break제어판의 시스템 열기.
Win + Tab에어로 3D 창 전환. [윈도운 버튼을 누르고 있는동안 Tab으로 전환.]
Win + B트레이 알림으로 포커스 이동.
Win + D바탕화면 보기/감추기.
Win + E윈도운 탐색기 실행.
Win + F검색.
Win + G모든 가젯창의 화면 상단으로 올리기.
Win + L컴퓨터 잠금.
Win + M모든 윈도우 최소화.
Win + P프로젝션 메뉴 열기.
Win + R명령어 실행 열기.
Win + SOneNote 스크린 크리핑 툴.
Win + T타스크에서 실행중인 윈도우의 미리보기 썸네일 보기.
Win + #윈도우 탐색기 빠른실행. 윈도우 탐색기가 여러개 떠 있을 경우에는 윈도우 탐색기 전환.
Win + =윈도우 돋보기 실행.
Win + [+/-]돋보기 확대 축소.
Win + Shift + Up Arrow세로 사이즈로 최대화.
Win + Shift + Down Arrow세로 사이즈 최대화 복원 및 최소화.
Win + Shift + Left Arrow좌측 모니터로 보내기.
Win + Shift + Right Arrow우측 모니터로 보내기.
Win + Shift + M전체창 최소화 복원.(Win + M 반대)
Win + Shift + TWin + T의 반대로 이동.
Win + Ctrl + F엑티브 디렉토리 검색 다이얼로그 열기.
Ctrl + Win + Tab에어로 3D 창전환 열기. 키를 띄워도 에어로 상태 고정.
Ctrl + Shift + Esc작업관리자 열기.


+ Recent posts