Problème de "récupération du clavier" sans fichier nib

Bonjour, je me suis lancé dans l'écriture de ma première application cocoa.

C'est un tout petit programme qui ouvre une fenêtre pour saisir un mot de passe et qui après validation le renvois sur la sortie standard. Il est destiné a être utilisé dans mes scripts bash (exécuté dans un contexte hors terminal) notamment pour la command "sudo" via les commandes :
<br />
[color=#808080]#&#33;/bin/bash[/color]<br />
export SUDO_ASKPASS=&#036;(dirname &quot;&#036;0&quot;)&quot;/[color=#ff0000]pwdbox[/color]&quot;<br />
SUDO=&quot;sudo -A&quot;<br />
&#036;SUDO ifconfig ........<br />




Donc dans un premier temps j'ai écris mon petit programme à  l'aide de l'interface builder et tout et tout, qui fonctionne correctement, et dans un deuxième temps je l'ai modifié afin de pouvoir sortir le "binaire" du package de l'application et le rendre autonome comme une application ligne de commande classique.

Voici donc le Main modifié :
<br />
[color=#808080]//<br />
//  main.m<br />
//  pwdbox<br />
//<br />
//  Created by Kirol on 01/02/12.<br />
//  Copyright 2012 __MyCompanyName__. All rights reserved.<br />
//[/color]<br />
#import &lt;Cocoa/Cocoa.h&gt;<br />
#import &quot;pwdboxAppDelegate.h&quot;<br />
<br />
int [color=#0000cd]MainNoBundle[/color](int argc, const char *argv[])<br />
{<br />
	pwdboxAppDelegate *delegate = [[[color=#ff0000]pwdboxAppDelegate[/color] alloc] [color=#ff0000]initNoBundle:TRUE[/color]];<br />
	NSApplication *app = [NSApplication sharedApplication];<br />
	[color=#808080]//MyNoBundleApp *app = [[MyNoBundleApp alloc ] init];<br />
  <br />
	//[app activateIgnoringOtherApps:YES];[/color]<br />
  <br />
	[app setDelegate:delegate];<br />
  <br />
 [color=#808080]   //NSLog( @&quot;Mode No Bundle&quot; );[/color]<br />
  <br />
	[app run];<br />
  <br />
	[delegate release];<br />
	return( 0 );<br />
}<br />
int main(int argc, char *argv[])<br />
{<br />
	NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];<br />
	NSFileManager *fileManager = [[NSFileManager alloc] init];<br />
	BOOL bExist = TRUE;<br />
	BOOL bDirectory;<br />
	NSString *bundlePath;<br />
	NSString *executablePath;<br />
	NSString *plistPath;<br />
	int iRet;<br />
  <br />
   [color=#0000cd] [[NSApplication sharedApplication] activateIgnoringOtherApps:YES];[/color]<br />
  <br />
	bundlePath = [[NSBundle mainBundle] bundlePath];<br />
	executablePath = [[NSBundle mainBundle] executablePath];<br />
	plistPath = [NSString stringWithFormat:@&quot;%@/Contents/Info.plist&quot;, bundlePath ];;<br />
  <br />
	[color=#808080]//NSLog( @&quot;bundlePath:%@&quot;, bundlePath  );<br />
	//NSLog( @&quot;executablePath:%@&quot;, executablePath  );<br />
	//NSLog( @&quot;plistPath:%@&quot;, plistPath  );[/color]<br />
  <br />
  <br />
	bExist = [fileManager fileExistsAtPath:plistPath isDirectory:&amp;bDirectory];<br />
  <br />
	[fileManager release];<br />
	[bundlePath release];<br />
	[executablePath release];<br />
	[plistPath release];<br />
  <br />
	if( bExist )<br />
		iRet = NSApplicationMain(argc,  (const char **) argv);<br />
	else<br />
		iRet = [color=#0000cd]MainNoBundle[/color](argc,  (const char **) argv);<br />
  <br />
	[pool drain];<br />
  <br />
	return iRet;<br />
}<br />




et la class pwdboxAppDelegate gérant le protocole NSApplicationDelegate :
<br />
[color=#808080]//<br />
//  pwdboxAppDelegate.m<br />
//  pwdbox<br />
//<br />
//  Created by Kirol on 01/02/12.<br />
//  Copyright 2012 __MyCompanyName__. All rights reserved.<br />
//[/color]<br />
#import &quot;pwdboxAppDelegate.h&quot;<br />
@implementation pwdboxAppDelegate<br />
@synthesize window;<br />
@synthesize btnPasswd;<br />
@synthesize txtPasswd;<br />
- (id)init {<br />
	return [self initNoBundle:FALSE];<br />
}<br />
- (id)initNoBundle:(BOOL)bNoBundle {<br />
  <br />
	bModeNoBundle = bNoBundle;<br />
  <br />
	return [super init];<br />
}<br />
- (void)initUI {<br />
  <br />
	CGFloat iHeight = 60;<br />
	CGFloat iWidth = 340;<br />
  <br />
  <br />
  [color=#808080]  //NSLog( @&quot;Init UI&quot; );[/color]<br />
	if( &#33;self.window ) {<br />
	  <br />
		self.window = [[NSWindow alloc] init];<br />
	}<br />
  <br />
	if( self.window ) {<br />
	  <br />
		//NSApplication *app = [NSApplication sharedApplication];<br />
	  <br />
		self.window.title = @&quot;Authentification&quot;;<br />
		[self.window setStyleMask:NSTitledWindowMask | NSClosableWindowMask];<br />
	   [color=#808080] //Taille de la fenetre[/color]<br />
		[self.window.contentView setFrame:NSMakeRect(0,0,iWidth,iHeight)];<br />
		[color=#808080]//déplacer et changer la taille de la fenêtre principale[/color]<br />
		[self.window setFrame:NSMakeRect(0,0,iWidth,iHeight) display:YES animate:YES];<br />
		[self.window center];<br />
	  <br />
		  <br />
	  <br />
		NSTextField *lblPasswd = [[NSTextField alloc] initWithFrame: NSMakeRect(10, 8, 100, 20)];<br />
		lblPasswd.stringValue = @&quot;Mot de passe : &quot;;<br />
		[lblPasswd setSelectable:NO];<br />
		[lblPasswd setEditable:NO];<br />
		[lblPasswd setBordered:NO];<br />
		[lblPasswd setDrawsBackground:NO];<br />
		[lblPasswd setBezeled:NO];<br />
		[self.window.contentView addSubview: lblPasswd];<br />
	  <br />
	  <br />
		self.txtPasswd = [[NSSecureTextField alloc] initWithFrame: NSMakeRect(105, 10, 150, 20)];<br />
		self.txtPasswd.stringValue = @&quot;&quot;;<br />
		[self.window.contentView addSubview: self.txtPasswd];<br />
	  <br />
	  <br />
		self.btnPasswd = [[NSButton alloc] initWithFrame: NSMakeRect(260, 0, 75, 35)];<br />
		self.btnPasswd.bezelStyle = NSRoundedBezelStyle;<br />
		self.btnPasswd.title = @&quot;Valider&quot;;<br />
		[self.window.contentView addSubview: self.btnPasswd];<br />
	  <br />
		// ACTION:<br />
	   [color=#808080] //delegate sur cette class afin de gerer la fermeture de la fenetre (voir - windowShouldClose plus bas)[/color]<br />
		[self.window setDelegate:self];<br />
	  <br />
		[color=#808080]//delegate sur cette class afin de gerer les touche ESC/RETURN (voir - control plus bas)[/color]<br />
		[self.txtPasswd setDelegate:self];<br />
	  <br />
		self.btnPasswd.target = self;<br />
		self.btnPasswd.action = @selector(validerPasswd:);<br />
	  <br />
	  <br />
		[color=#808080]//Gestion du Focus<br />
		//[self.window makeFirstResponder:nil];<br />
	  <br />
		//[self.window becomeMainWindow];<br />
		//[self.window becomeKeyWindow];[/color]<br />
	   [color=#ff0000] [self.window makeFirstResponder:self.txtPasswd];<br />
       [self.window setInitialFirstResponder:self.txtPasswd];[/color]<br />
	}<br />
  <br />
}<br />
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {<br />
[color=#808080]// Insert code here to initialize your application[/color]<br />
  <br />
  <br />
	[color=#ff0000]if( bModeNoBundle ) {<br />
		[self initUI];<br />
	}[/color]<br />
	  <br />
	[color=#808080]// Fenetre En Topmost[/color]<br />
	if( self.window ){<br />
		[self.window setLevel: NSMainMenuWindowLevel];<br />
		[self.window makeKeyAndOrderFront:self];<br />
	}<br />
  <br />
}<br />




Mais voila le probléme : je sors le "binaire pwdbox" de son package et le colle sur le bureau, le lance, une fenêtre terminal s'ouvre et ma fenêtre de saisie s'affiche mais ...

1: la fenêtre n'est pas active alors que la commande suivante presente dans le main était censée corriger ce probléme:
<br />
[color=#0000cd][[NSApplication sharedApplication] activateIgnoringOtherApps:YES];[/color]<br />


2: Qd j'active la fenêtre et tape du texte, le texte s'affiche dans la fenêtre du terminal et non dans le TextField ma fenêtre image/crybaby.gif' class='bbc_emoticon' alt=' :'( ' />



Je ne m'en sors pas, une bonne âme pourrait il jeter un coup d'oeil et m'indiquer ce que j'ai oublié de faire ?



Merci d'avoir pris le temps de me lire.

Réponses

  • KirolKirol Membre
    février 2012 modifié #2
    Re, j'ai résolu mes problèmes en faisant appel à  la méthode suivante dans le main :
    <br />
    // In Snow Leopard, programs without application bundles and Info.plist files<br />
    // don&#39;t get a menubar and can&#39;t be brought to the front unless the presentation option is changed:<br />
    [NSApp setActivationPolicy:NSApplicationActivationPolicyRegular];<br />
    




    Information trouvé sur ce site http://cocoawithlove...rogramming.html



    Je vous remets le code complet du programme qui pourra peut être servir a un newbie comme moi



    Main.m:
    <br />
    //<br />
    //  main.m<br />
    //  pwdbox<br />
    //<br />
    //  Created by Kirol on 01/02/12.<br />
    //  Copyright 2012 __MyCompanyName__. All rights reserved.<br />
    //<br />
    <br />
    #import &lt;Cocoa/Cocoa.h&gt;<br />
    #import &quot;pwdboxAppDelegate.h&quot;<br />
    <br />
    <br />
    int MainNoBundle(int argc, const char *argv[])<br />
    {<br />
        pwdboxAppDelegate *delegate = [[pwdboxAppDelegate alloc] initNoBundle:TRUE];<br />
    <br />
        //NSLog( @&quot;Mode No Bundle&quot; );<br />
    <br />
        [NSApp setDelegate:delegate];<br />
    <br />
        //MENU<br />
        NSMenu *menubar = [[NSMenu new] autorelease];<br />
        NSMenuItem *appMenuItem = [[NSMenuItem new] autorelease];<br />
        [menubar addItem:appMenuItem];<br />
        [NSApp setMainMenu:menubar];<br />
    <br />
    <br />
        NSMenu *appMenu = [[NSMenu new] autorelease];<br />
        NSString *appName = [[NSProcessInfo processInfo] processName];<br />
        NSString *quitTitle = [@&quot;Quit &quot; stringByAppendingString:appName];<br />
        NSMenuItem *quitMenuItem = [[[NSMenuItem alloc] initWithTitle:quitTitle<br />
                                                        action:@selector(terminate: )<br />
                                                        keyEquivalent:@&quot;q&quot;] autorelease];<br />
        [appMenu addItem:quitMenuItem];<br />
        [appMenuItem setSubmenu:appMenu];<br />
    <br />
        [NSApp run];<br />
    <br />
        [NSApp setDelegate:nil];<br />
        [delegate release];<br />
        return( 0 );<br />
    }<br />
    <br />
    int main(int argc, char *argv[])<br />
    {<br />
        NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];<br />
        NSFileManager *fileManager = [[NSFileManager alloc] init];<br />
        BOOL bExist = TRUE;<br />
        BOOL bDirectory;<br />
        NSString *bundlePath;<br />
        NSString *executablePath;<br />
        NSString *plistPath;<br />
        int iRet;<br />
    <br />
        [NSApplication sharedApplication];<br />
        [NSApp setActivationPolicy:NSApplicationActivationPolicyRegular];<br />
        [NSApp activateIgnoringOtherApps:YES];<br />
    <br />
        bundlePath = [[NSBundle mainBundle] bundlePath];<br />
        executablePath = [[NSBundle mainBundle] executablePath];<br />
        plistPath = [NSString stringWithFormat:@&quot;%@/Contents/Info.plist&quot;, bundlePath ];;<br />
    <br />
        //NSLog( @&quot;bundlePath:%@&quot;, bundlePath  );<br />
        //NSLog( @&quot;executablePath:%@&quot;, executablePath  );<br />
        //NSLog( @&quot;plistPath:%@&quot;, plistPath  );<br />
    <br />
        bExist = [fileManager fileExistsAtPath:plistPath isDirectory:&amp;bDirectory];<br />
    <br />
        [fileManager release];<br />
    <br />
        if( bExist )<br />
            iRet = NSApplicationMain(argc,  (const char **) argv);<br />
        else<br />
            iRet = MainNoBundle(argc,  (const char **) argv);<br />
    <br />
        [pool drain];<br />
    <br />
        return iRet;<br />
    }<br />
    






    pwdboxAppDelegate.h:
    <br />
    //<br />
    //  pwdboxAppDelegate.h<br />
    //  pwdbox<br />
    //<br />
    //  Created by Kirol on 01/02/12.<br />
    //  Copyright 2012 __MyCompanyName__. All rights reserved.<br />
    //<br />
    <br />
    #import &lt;Cocoa/Cocoa.h&gt;<br />
    <br />
    @interface pwdboxAppDelegate : NSObject &lt;NSApplicationDelegate,NSWindowDelegate,NSTextFieldDelegate&gt; {<br />
    <br />
        @private<br />
            NSWindow *window;<br />
            NSTextField *lblPasswd;<br />
            NSSecureTextField *txtPasswd;<br />
            NSButton *btnPasswd;<br />
            BOOL bModeNoBundle;<br />
    }<br />
    - (id)initNoBundle:(BOOL)bNoBundle;<br />
    - (IBAction)validerPasswd:(id)sender;<br />
    - (IBAction)annulerPasswd:(id)sender;<br />
    <br />
    @property (assign) IBOutlet NSWindow *window;<br />
    @property (assign) IBOutlet NSTextField *lblPasswd;<br />
    @property (assign) IBOutlet NSSecureTextField *txtPasswd;<br />
    @property (assign) IBOutlet NSButton *btnPasswd;<br />
    <br />
    @end
    






    pwdbosAppDelegate.m:
    <br />
    //<br />
    //  pwdboxAppDelegate.m<br />
    //  pwdbox<br />
    //<br />
    //  Created by Kirol on 01/02/12.<br />
    //  Copyright 2012 __MyCompanyName__. All rights reserved.<br />
    //<br />
    <br />
    #import &quot;pwdboxAppDelegate.h&quot;<br />
    <br />
    @implementation pwdboxAppDelegate<br />
    <br />
    @synthesize window;<br />
    @synthesize lblPasswd;<br />
    @synthesize txtPasswd;<br />
    @synthesize btnPasswd;<br />
    <br />
    <br />
    - (id)init {<br />
        return [self initNoBundle:FALSE];<br />
    }<br />
    <br />
    - (id)initNoBundle:(BOOL)bNoBundle {<br />
    <br />
        bModeNoBundle = bNoBundle;<br />
    <br />
        return [super init];<br />
    }<br />
    <br />
    - (void)initUI {<br />
    <br />
        CGFloat iHeight = 60;<br />
        CGFloat iWidth = 340;<br />
    <br />
    <br />
        //NSLog( @&quot;Init UI&quot; );<br />
        if( &#33;self.window ) {<br />
    <br />
            self.window = [[NSWindow alloc] init];<br />
        }<br />
    <br />
        if( self.window ) {<br />
    <br />
    <br />
            self.window.title = @&quot;Authentification&quot;;<br />
            [self.window setStyleMask:NSTitledWindowMask | NSClosableWindowMask];<br />
            //Taille de la fenetre<br />
            [self.window.contentView setFrame:NSMakeRect(0,0,iWidth,iHeight)];<br />
            //déplacer et changer la taille de la fenêtre principale<br />
            [self.window setFrame:NSMakeRect(0,0,iWidth,iHeight) display:YES animate:YES];<br />
            //self.window.center;<br />
            [self.window center];<br />
    <br />
    <br />
    <br />
            self.lblPasswd = [[NSTextField alloc] initWithFrame: NSMakeRect(10, 8, 100, 20)];<br />
            self.lblPasswd.stringValue = @&quot;Mot de passe : &quot;;<br />
            [self.lblPasswd setSelectable:NO]; <br />
            [self.lblPasswd setEditable:NO];<br />
            [self.lblPasswd setBordered:NO];<br />
            [self.lblPasswd setDrawsBackground:NO];<br />
            [self.lblPasswd setBezeled:NO];<br />
            //[self.lblPasswd setBezelStyle:NSRoundedBezelStyle];<br />
            [self.window.contentView addSubview: self.lblPasswd];<br />
    <br />
    <br />
    <br />
            self.txtPasswd = [[NSSecureTextField alloc] initWithFrame: NSMakeRect(105, 10, 150, 20)];<br />
            self.txtPasswd.stringValue = @&quot;&quot;;<br />
            [self.window.contentView addSubview: self.txtPasswd];<br />
    <br />
    <br />
            self.btnPasswd = [[NSButton alloc] initWithFrame: NSMakeRect(260, 0, 75, 35)];<br />
            self.btnPasswd.bezelStyle = NSRoundedBezelStyle;<br />
            self.btnPasswd.title = @&quot;Valider&quot;;<br />
            [self.window.contentView addSubview: self.btnPasswd];<br />
    <br />
    <br />
            // ACTION:<br />
            //delegate sur cette class afin de gerer la fermeture de la fenetre (voir - windowShouldClose plus bas)<br />
            [self.window setDelegate:self];<br />
    <br />
            //delegate sur cette class afin de gerer les touche ESC/RETURN (voir - control plus bas)<br />
            [self.txtPasswd setDelegate:self];<br />
    <br />
            self.btnPasswd.target = self;<br />
            self.btnPasswd.action = @selector(validerPasswd:);<br />
    <br />
    <br />
            //Gestion du Focus<br />
            //[self.window makeFirstResponder:nil];<br />
    <br />
            //[self.window becomeMainWindow];<br />
            //[self.window becomeKeyWindow];<br />
            //[[scrollView window] makeFirstResponder:[self firstTextView]];<br />
            //[[scrollView window] setInitialFirstResponder:[self firstTextView]];    // So focus won&#39;t be stolen (2934918)<br />
            //[self.window.contentView makeFirstResponder:txtPasswd];<br />
            //[self.window.contentView setInitialFirstResponder:txtPasswd];<br />
        }<br />
    <br />
    }<br />
    <br />
    - (void)releaseUI {<br />
        if( self.window ) {<br />
    <br />
            [self.lblPasswd release];<br />
            [self.txtPasswd release];<br />
            [self.btnPasswd release];<br />
    <br />
            [self.window release];<br />
            //NSLog( @&quot;Fin APP&quot; );<br />
        }<br />
    }<br />
    <br />
    - (void)dealloc {<br />
    <br />
        if( bModeNoBundle ) {<br />
            [self releaseUI];<br />
        }<br />
    <br />
        [super dealloc];<br />
    <br />
        return;<br />
    }<br />
    <br />
    - (void)applicationDidFinishLaunching:(NSNotification *)aNotification {<br />
    // Insert code here to initialize your application <br />
    <br />
    <br />
        if( bModeNoBundle ) {<br />
            [self initUI];<br />
        }<br />
    <br />
        // Fenetre En Topmost<br />
        if( self.window ){<br />
    <br />
            [self.window setLevel: NSMainMenuWindowLevel];<br />
            [self.window makeKeyAndOrderFront:self];<br />
        }<br />
    <br />
    }<br />
    <br />
    - (IBAction)validerPasswd:(id)sender {<br />
    <br />
        NSString *passwd = [txtPasswd stringValue];<br />
        //NSLog( @&quot;Txt=%@&quot;, passwd );<br />
    <br />
        if( [passwd length] &gt; 0 ) {<br />
            printf(&quot;%s\n&quot;, [passwd UTF8String] );<br />
    <br />
            //[NSApp terminate:self];<br />
            [NSApp stop:sender];<br />
    <br />
        } else {<br />
            NSBeep();<br />
        }<br />
    <br />
        [passwd release];<br />
    <br />
    }<br />
    <br />
    - (IBAction)annulerPasswd:(id)sender {<br />
    <br />
        //[NSApp terminate:self];<br />
        [NSApp stop:sender];<br />
    }<br />
    <br />
    <br />
    -(void)maFonction:(BOOL)up<br />
    {<br />
        if (up)<br />
            NSLog(@&quot;J&#39;ai appuyé sur UP&#33;&quot;);<br />
        else<br />
            NSLog(@&quot;J&#39;ai appuyé sur DOWN&#33;&quot;);<br />
    }<br />
    <br />
    - (BOOL)control:(NSControl *)control textView:(NSTextView *)textView doCommandBySelector:(SEL)commandSelector<br />
    {<br />
    <br />
        NSString *s=NSStringFromSelector(commandSelector);<br />
    <br />
        /*<br />
        if ([s isEqualToString:@&quot;moveUp:&quot;])<br />
        {<br />
            [self maFonction:TRUE];<br />
            return TRUE;<br />
        }<br />
        else if ([s isEqualToString:@&quot;moveDown:&quot;])<br />
        {<br />
            [self maFonction:NO];<br />
            return TRUE;<br />
        }<br />
        else <br />
            */<br />
        if ([s isEqualToString:@&quot;cancelOperation:&quot;]) // Esc<br />
        {<br />
            [self annulerPasswd:self];<br />
            return TRUE;<br />
        }<br />
        else if ([s isEqualToString:@&quot;insertNewline:&quot;]) // Return<br />
        {<br />
            [self validerPasswd:self];<br />
            return TRUE;<br />
        }<br />
        return 0;<br />
    }<br />
    <br />
    - (BOOL)windowShouldClose:(id)sender {<br />
    <br />
        //NSLog( @&quot;Close ?&quot; );<br />
        [self annulerPasswd:sender];<br />
        return FALSE;<br />
    }<br />
    <br />
    @end
    




  • AliGatorAliGator Membre, Modérateur
    En effet c'est sioux, merci d'avoir partagé l'info
  • devulderdevulder Membre
    février 2012 modifié #4
    Bonjour,



    Pour la construction de la fenêtre tu te complique la vie.



    Utilise la méthode :


    <br />
    - (id)initWithContentRect:(NSRect)contentRect styleMask:(NSUInteger)windowStyle backing:(NSBackingStoreType)bufferingType defer:(BOOL)deferCreation<br />
    




    Il faut mieux utiliser la méthode d'initialisation préconiser par la classe.
Connectez-vous ou Inscrivez-vous pour répondre.