次のようにします
1.デスクトップ作業領域を取得
SystemParametersInfo関数でデスクトップ作業領域を取得します。
2.ウインドウ位置、サイズを取得
GetWindowRect関数で自分のウインドウサイズと位置を取得します。
3.前回起動の位置をレジストリより取得
GetMyRegLong関数は別に用意したレジストリアクセスのための関数です。レジストリキーが見つからなかったときは、初回起動とみなします。
4a.初回起動時ならウインドウをデスクトップの中央に移動
デスクトップ作業域とウインドウ位置から計算で移動先の位置を求めます。
4b.それ以外ならデスクトップからはみ出すのを修正
例えば、アプリケーションの起動時にウインドウの位置が次のようになっていたとすると
(実際の処理ではウインドウはまだ表示させない)

次のように移動させます。こうすることで、ボタン類がデスクトップの外に出てしまうのを防ぎます。

5.ウインドウの移動
MoveWindow関数でウインドウを移動します。
次のような関数を作ると便利です。この例ではダイアログベースアプリでの使用を前提としているため、ウインドウのリサイズは行いません。
//////////////////////////////////////////////////////////////////////////////
//windowPosSet2
//ウインドウ位置の調整(サイズの再調整はしない)
//////////////////////////////////////////////////////////////////////////////
/*
引数: HWND hWnd 調整するウインドウのハンドル
戻り値:なし
*/
void windowPosSet2(HWND hWnd)
{
RECT rect;
RECT newrect;
int nCX;
int nCY;
//デスクトップ作業領域を取得
SystemParametersInfo(SPI_GETWORKAREA,0,&rect,0);
nCX=rect.right;
nCY=rect.bottom;
//ウインドウrectを取得
GetWindowRect(hWnd,&rect);
//前回の位置をレジストリより取得する
if((GetMyRegLong(NULL,"WindowPos_top",&newrect.top) == FALSE) ||
(GetMyRegLong(NULL,"WindowPos_left",&newrect.left) == FALSE))
{
//ウインドウをデスクトップの中央へ
newrect.top=nCY/2-(rect.bottom-rect.top)/2;
newrect.left=nCX/2-(rect.right-rect.left)/2;
}else
{
//はみ出し禁止
if(nCY < newrect.top+rect.bottom-rect.top)
{ //下
newrect.top-=newrect.top+rect.bottom-rect.top-nCY;
}
if(0 > newrect.top)
{ //上
newrect.top=0;
}
if(nCX < newrect.left+rect.right-rect.left)
{ //右
newrect.left-=newrect.left+rect.right-rect.left-nCX;
}
if(0 > newrect.left)
{ //左
newrect.left=0;
}
}
newrect.right=newrect.left+rect.right;
newrect.bottom=newrect.top+rect.bottom;
//ウインドウの移動
MoveWindow(hWnd,newrect.left,
newrect.top,
newrect.right-newrect.left,
newrect.bottom-newrect.top,FALSE);//この時点では描画しない
}
また、このコードはWinMain関数中の
ShowWindow(hDlg, nCmdShow);
UpdateWindow(hDlg);
の直前に実行するようにします。MoveWindowで描画しないのはこのためです。